Exploring React 19: The New use API with Suspense

Kartik Mittal

--

React 19 has introduced a lot of exciting features, but in this article we are going to focus on new use API with Suspense. Lets take a usual scenario where you need to hit a backend api as soon as your component mounts. So most probably you are going to implement this in following manner —

  1. Declaring atleast two state variables, one for loading state and other one for storing response or error.
  2. Adding a useEffect hook with empty dependency array in which you are going to call your async function to update loading and response state variable which will update the UI.
  3. Other than this you are going to handle different cases on the basis of state variables like what to render if state is loading or if response is null.

What if I say, you don’t need to do all this from now. Interesting right? Let’s directly deep dive into code comparing the old and new approach to see how we can achieve this.

Old Approach —

In above code as you can see that we are using isLoading and response state variables for handling loading, response and error state in our child component (AlbumList), which further using useEffect hook to trigger the api when component mounts.

New Approach —

So, what’s happening here? Let’s see step by step —

  1. We have wrapped our child component (AlbumList) with Suspense which allow us to define a fallback component, that will be shown to user until promise passed to the child component will not get fulfilled (reject or resolve).
  2. For getting data from backend api, we are using new use API at line 5, which suspends the execution of component until promise passed to it will not get fulfilled. It means code written below this line will not get executed for that time whether there is any useEffect or any return method. It’s kind of freezing the component until the execution gets completed. Once promise gets fulfilled, component will be rerendered and data will be shown.
  3. Also, if you don’t want to handle promise error by yourself, then you can omit try catch block (see getAlbums function above) and can rely on ErrorBoundary component in react. Just you need to wrap <Suspense /> with <ErrorBoundary /> providing a fallback that will be rendered if any error occurs.

Points to remember —

  • use API does not support promises created in render. So, you cannot create a promise inside child component and call inside use. Like this —
const AlbumsList = () => {

async function getAlbums() {
await new Promise(resolve => {
setTimeout(resolve, 3000);
});

return [
{
id: 13,
title: 'Let It Be',
year: 1970,
}
];
}

const albumsListOrError = use(getAlbums()); //This will trigger unnecessary rerenders and execution will not go beyond this point.
return <></>;
}
  • Unlike React Hooks, use can be called within loops and conditional statements like if. Like React Hooks, the function that calls use must be a Component or a Hook.
  • use can be used without Suspense but only Suspense-enabled data sources will activate the Suspense component. They include:
  1. Data fetching with Suspense-enabled frameworks like Relay and Next.js
  2. Lazy-loading component code with lazy
  3. Reading the value of a cached Promise with use

References

Enjoyed this article? Have thoughts or questions about React.js or React Native?

Follow me on LinkedIn for more insights and updates, and leave a comment below — I’d love to hear from you! If you found this article helpful, give it a round of applause and share it with your colleagues to spread the knowledge.

--

--

Responses (1)