React has features like Suspense to make streaming data and content loading smoother than ever.
Streaming data in React with Suspense is a game-changer. It allows us to progressively load data and render content as it becomes available, reducing the initial load time of our applications. In this article, we'll explore how to implement streaming in React using Suspense.
Streaming a List of Items
Let's start with a simple example where we load a list of items from an API and render them progressively as they arrive. We'll use the React.Suspense component to wrap our asynchronous data fetching.
import React, { Suspense } from 'react';
const fetchItems = () => {
// Simulate an API call with setTimeout
return new Promise((resolve) => {
setTimeout(() => {
resolve(['Item 1', 'Item 2', 'Item 3']);
}, 2000);
});
};
const ItemList = () => {
const items = fetchItems();
return (
<div>
<h1>Streaming Items</h1>
<Suspense fallback={<div>Loading...</div>}>
{items.map((item, index) => (
<Item key={index} item={item} />
))}
</Suspense>
</div>
);
};
const Item = ({ item }) => {
return <div>{item}</div>;
};
export default ItemList;In the above code:
- We define a function
fetchItemsthat simulates an API call, returning a promise after 2 seconds. - Inside the
ItemListcomponent, we useReact.Suspenseto specify a fallback UI while the data is loading. - We map over the items and render them as they arrive.
With this setup, the items will render progressively as they are fetched, providing a smoother user experience.
Handling Errors
Streaming data can also handle errors gracefully. If an error occurs during data fetching, we can use the React.ErrorBoundary to capture and display the error to the user.
import React, { Suspense } from 'react';
// ...fetchItems function
const ErrorBoundary = (props) => {
return (
<React.ErrorBoundary
fallback={(error) => (
<div>
<h2>Error: {error.message}</h2>
</div>
)}
>
{props.children}
</React.ErrorBoundary>
);
};
const ItemList = () => {
return (
<div>
<h1>Streaming Items</h1>
<ErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>
{fetchItems().map((item, index) => (
<Item key={index} item={item} />
)}
</Suspense>
</ErrorBoundary>
</div>
);
};
// ...Item component
export default ItemList;Here, we wrap our rendering components in an ErrorBoundary component, which will capture and display any errors that occur during the streaming process.
Conclusion
With the examples provided, you can start implementing streaming in your React applications today.
