React 16.6 has added a <Suspense> component that allows you to “wait” for some code to load and declaratively specify a loading state (like a spinner) while you’re waiting. React Suspense was pitched as an improvement to the developer experience when dealing with asynchronous data fetching within React apps. This is a huge deal because everyone who is building dynamic web applications knows that this is still one of the major pain points and one of the things that bring huge boilerplates with it.
Let’s see what suspense is and how it’s used.
What is React Suspense?
Suspense is a component that wraps the custom components and enables them to communicate to React that they’re waiting for some data to load before the component is rendered.
It is important to note that Suspense is neither a data-fetching library like react-async nor is it a way to manage a state like Redux. It simply prevents your components from rendering to the DOM until some asynchronous operation (i.e., a network request) is completed.
Here, the StudentList component is wrapped with a Suspense component that has a fallback prop. This means that if StudentList is waiting for some asynchronous operation, such as getting the lists of students from an API, React will render <p>loading..</p> to the DOM instead. The StudentList component is rendered only after the promises and API’s are resolved.
This can also be written as –
Let’s look at some scenarios related to the same –
What If StudentList was the one who triggered the operation?
In that case, we would have to move the loading check from the parent component to the StudentList component.
What if there are more components apart from StudentList, each triggering their async requests?
This would mean that each child component would have to manage their loading states independently, and that would make it tricky to organize the data loading operations in a way that doesn’t lead to a janky UX.
Take a look at the example below –
Here's an example that I have implemented on the CodeSandbox:
How to use Suspense to display a loader?
React comes with the support of lazy components. Instead of handling the dynamic import Promise, React.lazy allows you to use the dynamic component like a statically imported one. React.lazy() is a new function in React that allows you to load react components lazily through code splitting without help from any additional libraries.
Lazy loading is the technique of rendering only needed or critical user interface items first, then quietly unrolling the non-critical items later. It is now fully integrated into the core React library itself. We formerly used react-loadable to achieve this but now we have react.lazy() in the React core.
Suspense is a component required by the lazy function basically used to wrap lazy components. Multiple lazy components can be wrapped with it. It takes a fallback property that accepts the react elements you want to render as the lazy component which is being loaded.
React.lazy takes a function that will execute the dynamic import. It returns a component that will run this function during its first rendering.
The resulting promise status is used by Suspense:
- to render the fallback during the chunk download (pending Promise)
- to render the real StudentList component once downloaded (resolved Promise)
Suspense helps us to coordinate asynchronous resources with our loader component rendering. We have already used it in the above example.
We have seen how to get started using the lazy and suspense components provided by React to load components lazily. The above example is a basic one as compared to the numerous possibilities these new features bring.
This was a quick introduction to “React.Suspense” and how it is used with code splitting. Stay tuned for our upcoming blog on ‘What Suspense will become in the future.’
A hint – It will be used for much more than just code splitting!
Here's a glimpse of the React team’s vision for what the future of React might look like, including some never before seen prototypes.