I'm struggling to find problems with using Suspense and React hooks.
There are several key problems with the React code below.
import { Suspense, useState, useEffect } from 'react';
const SuspensefulUserProfile = ({ userId }) => {
const [data, setData] = useState({});
useEffect(() => {
fetchUserProfile(userId).then((profile) => setData(profile));
}, [userId, setData])
return (
<Suspense>
<UserProfile data={data} />
</Suspense>
);
};
const UserProfile = ({ data }) => {
return (
<>
<h1>{data.name}</h1>
<h2>{data.email}</h2>
</>
);
};
const UserProfileList = () => {
<>
<SuspensefulUserProfile userId={1} />
<SuspensefulUserProfile userId={2} />
<SuspensefulUserProfile userId={3} />
</>
};
Let me know what they are.
I found two key problems.
setdata
in useEffect
dependency arraysuspense
fallback
props.I think there is still one key problem remaining.
One weird thing is why userId
needs to be included in the dependency array.
You misused Suspense
to its core, at least until suspense for data fetching is available.
Suspense only currently works with React.lazy
components, not with arbitrary 'loading' states of your application. For instance, how should React figure out that your data
is loading?
The only use for Suspense
is to allow showing some fallback while React loads a lazy component. For other types of lazy loading app data you can implement your own fallback, as in:
const SuspensefulUserProfile = ({ userId }) => {
const [data, setData] = useState();
useEffect(() => {
fetchUserProfile(userId).then(setData);
}, [userId])
return data ? <UserProfile data={data} /> : 'Loading...';
};
React 19 now supports first class loading states. You can revise your code as follows:
import { Suspense, useMemo, use } from 'react';
const SuspensefulUserProfile = ({ userId }) => {
return (
<Suspense>
<UserProfile userId={userId} />
</Suspense>
);
};
const UserProfile = ({ userId }) => {
const promise = useMemo(() => fetchUserProfile(userId), [userId])
const data = use(promise)
return (
<>
<h1>{data.name}</h1>
<h2>{data.email}</h2>
</>
);
};
const UserProfileList = () => {
<>
<SuspensefulUserProfile userId={1} />
<SuspensefulUserProfile userId={2} />
<SuspensefulUserProfile userId={3} />
</>
};