Suspense in React
If you've been into react for a while, you might have encountered problems where you are fetching some data into a react component. While the data is being fetched you might want to show the loading state (maybe a spinner component), to do this you have to check the status of the request and show the loading state accordingly. Well not anymore, React 18 has introduced a new pattern called <Suspense>
. Let's see how it works today!
Note: At this time of writing, as per the React docs, Only Suspense-enabled data sources will activate the Suspense component. Suspense does not detect when data is fetched inside an Effect or event handler. So, to implement it in plain React we will have to do some workarounds to get this working. For this post, I'm considering the suspense is being used in Nextjs V.13 (App Router). Since it supports it out of the box it would be easy to understand it properly.
What is Suspense
By the definition given on the official react docs, <Suspense>
lets you display a fallback until its children have finished loading. In simple words, Suspense lets you render the loading state or component while the children of the Suspense component are fetching some data, that is doing some asynchronous task. Suspense makes it easy to handle the loading state of the component without writing all the loading state logic from scratch.
Syntax
<Suspense fallback={<Spinner />}>{/* children */}</Suspense>
Props
Suspense only takes two props, one is a fallback, and the other is children.
-
children Children is the prop that any react component has. It is the UI that we want to render on the screen. If the children are fetching some data, it will trigger their nearest suspense boundary, and the fallback UI will be shown as a placeholder for the children.
-
fallback: fallback is the UI that will be rendered on the screen while the children components are fetching the data. It is like a placeholder and this can be a React node. We can assign a component or write the inline JSX as the value of the fallback. Once the children component is done with their data fetching, Suspense will render the children and will remove the fallback UI from the screen. We can show the loading skeleton or a simple spinner as a fallback UI.
Example
<Suspense fallback={<Spinner />}>
<Posts />
</Suspense>
In the above example, the <Post />
component fetches some posts from a server, while the data is being fetched the <Spinner />
component will be shown. Once the fetching is done, the <Posts />
will be rendered on the screen.
Multiple Children
<Suspense fallback={<Spinner />}>
<Header />
<Posts />
<Projects />
</Suspense>
In the case of multiple children, it will consider the whole tree component tress as a single unit. Even if any component from the children tree is fetching some data it will render the fallback UI.
Nasted <Suspense>
<Suspense fallback={<AppSkeleton />}>
<Header />
<Suspense fallback={<PostsSkeleton />}>
<Posts />
</Suspense>
<Suspense fallback={<ProjectsSkeleton />}>
<Projects />
</Suspense>
<Footer />
</Suspense>
In case of nested use of <Suspense>
, it will be invoked in the parent-children nested sequence, Let's understand In the above example, here
- The
<AppSkeleton />
will be shown while the header fetches some data (suppose some navigation links from a CMS). - Once the
<Header>
is done with its fetching, it will be rendered on the screen along with the fallback of the posts and projects and the footer component. - Now whoever from the
<Posts />
and<Header />
completes the data fetching first, will be rendered on the screen.
That's what is Suspense in React. It has simplified the complexity of handling the loading state on the component level. To learn more about Suspense check the given resources below. That's all for this blog, I hope you learned something. Stay tuned!