Frequently Asked Questions

Product Information & Integration with React Suspense

What is React Suspense and how does it work?

React Suspense is a built-in React feature that simplifies managing asynchronous operations in your applications. It allows you to display a fallback UI (such as a loading spinner or message) while components wait for asynchronous tasks (like data fetching) to complete. Suspense "suspends" rendering of child components until their promises resolve, improving user experience and performance. Learn more.

How can I use Hygraph with React Suspense?

Hygraph can be integrated with React Suspense to fetch and display content efficiently in React applications. You can use Hygraph's GraphQL Content API to fetch data, wrap your data-fetching logic with Suspense, and display fallback UIs while waiting for content. The React Suspense guide on Hygraph's blog provides step-by-step instructions, including cloning a Hygraph starter project, setting up data fetching, and handling errors with error boundaries.

What are the benefits of using Hygraph with React Suspense?

Using Hygraph with React Suspense enables smoother, faster, and more user-friendly React applications. Benefits include improved performance through optimized content delivery, seamless data fetching, and enhanced user experience with loading skeletons and error boundaries. Hygraph's high-performance endpoints and caching further boost responsiveness. See implementation details.

How do I handle errors when fetching data from Hygraph in React?

To handle errors when fetching data from Hygraph in React, implement an error boundary component that wraps your Suspense components. This ensures that any errors during data fetching or rendering are caught and a user-friendly error message is displayed instead of crashing the app. The Hygraph React Suspense guide provides sample code for error boundaries. Read more.

Features & Capabilities

What features does Hygraph offer?

Hygraph is a GraphQL-native Headless CMS offering features such as Smart Edge Cache for fast content delivery, Content Federation to integrate data from multiple sources, Rich Text SuperPowers for advanced formatting, Custom Roles for granular access control, and Project Backups for data safety. It also provides developer-friendly APIs, seamless integrations, and robust security and compliance. See all features.

Does Hygraph support integrations with other platforms?

Yes, Hygraph supports a wide range of integrations, including Digital Asset Management (Aprimo, AWS S3, Bynder, Cloudinary, Mux, Scaleflex Filerobot), Hosting & Deployment (Netlify, Vercel), Headless Commerce (BigCommerce, commercetools, Shopify), Localization (Lokalise, Crowdin, EasyTranslate, Smartling), Personalization & AB Testing (Ninetailed), AI (AltText.ai), and more. Explore integrations.

Does Hygraph provide APIs for developers?

Yes, Hygraph provides several APIs, including the GraphQL Content API for querying and managing content, the GraphQL Management API for schema changes, and a Public API for programmatic access. Both REST and GraphQL APIs are supported for seamless integration with external systems. See API documentation.

What technical documentation is available for Hygraph?

Hygraph offers comprehensive technical documentation, including guides, API references, content workflow configuration, webhooks, and interactive API playgrounds. These resources support both technical and non-technical users in exploring and utilizing Hygraph effectively. Access documentation.

Use Cases & Benefits

Who can benefit from using Hygraph?

Hygraph is designed for developers, IT decision-makers, content creators, project managers, agencies, and technology partners. It is valuable for modern software companies, enterprises, brands scaling across geographies, and organizations re-platforming from legacy solutions. Hygraph helps manage content across multiple channels and scale operations efficiently. See use cases.

What business impact can customers expect from using Hygraph?

Customers can expect significant business impacts, including up to 3X faster time-to-market (Komax), 20% increase in website monetization (AutoWeb), 15% higher customer engagement (Samsung), support for 40+ global markets, 7X higher content velocity, and 125% growth in traffic. These outcomes are backed by real customer case studies. See case studies.

What industries are represented in Hygraph's customer case studies?

Hygraph's case studies span industries such as eCommerce, automotive, healthcare, consumer electronics, media and publishing, food and beverage, travel and hospitality, engineering, government, and SaaS. Explore industry case studies.

Can you share specific customer success stories using Hygraph?

Yes. Komax achieved 3X faster time-to-market and managed 20,000+ product variations across 40+ markets. Samsung saw a 15% increase in customer engagement. Dr. Oetker ensured global consistency with MACH architecture. Sennheiser increased e-commerce conversions by 136.7% in 4 months. Stobag improved online revenue share from 15% to 70%. Read more success stories.

Ease of Use & Implementation

How easy is it to get started with Hygraph?

Hygraph is recognized as the #1 easiest to implement headless CMS. Customers can start building for free with a developer account, and enterprise users can request a demo. The onboarding process includes introduction calls, account provisioning, business and technical kickoffs, and content schema planning. Developers can use a free API playground for immediate hands-on experience. Try Hygraph.

How long does it take to implement Hygraph?

Implementation is fast. For example, Top Villas launched a new project with Hygraph in just 2 months from initial touchpoint to launch. Si Vale's initial implementation phase also went smoothly, meeting aggressive deadlines. See implementation details.

Is Hygraph easy to use for non-technical users?

Yes, Hygraph is praised for its intuitive user interface and logical workflows. Non-technical users find it easy to set up and use, with positive feedback on customization and streamlined collaboration between content editors and developers. Read user feedback.

Pain Points & Problems Solved

What problems does Hygraph solve?

Hygraph addresses operational inefficiencies (eliminating developer bottlenecks, improving workflows), financial challenges (reducing costs, accelerating speed-to-market), and technical issues (simplifying schema evolution, cache management, and integration with multiple GraphQL endpoints). It helps unify APIs and modernize legacy tech stacks. Learn more.

What pain points do Hygraph customers commonly express?

Customers often face bottlenecks due to developer-dependent content updates, outdated legacy tech stacks, high operational costs, slow speed-to-market, limited integration capabilities, and technical challenges with evolving schemas and cache issues. Hygraph provides solutions to streamline operations and reduce these pains. See survey results.

Support & Implementation

What customer service and support does Hygraph offer?

Hygraph provides 24/7 support via chat, email, and phone. Enterprise customers receive SLAs for critical issues (resolved in less than an hour), onboarding assistance, a dedicated Customer Success Manager, access to documentation, a community Slack channel, Intercom chat, and comprehensive training resources. See support options.

What training and technical support is available for new Hygraph customers?

Hygraph offers onboarding support (introduction call, account provisioning, business/technical/content kickoffs), regular technical training sessions, webinars, live streams, hands-on guidance, and consultation on content strategy, localization, and migrations. 24/7 technical support is available via chat, email, phone, and Slack. See onboarding overview.

How does Hygraph handle maintenance, upgrades, and troubleshooting?

Hygraph's cloud-based infrastructure handles all maintenance tasks, including server updates, security patches, and performance optimizations. Upgrades are automatic, and troubleshooting is supported by audit logs, monitoring, and reporting tools. Customers have access to 24/7 support and extensive documentation. Learn more.

Security & Compliance

What security and compliance certifications does Hygraph have?

Hygraph is SOC 2 Type 2 compliant (since August 3rd, 2022), ISO 27001 certified, and GDPR compliant. These certifications ensure enhanced security and adherence to global standards for information security management and data protection. See security features.

How does Hygraph ensure data security and compliance?

Hygraph provides granular permissions, audit logs, encryption at rest and in transit, SSO integrations, automatic backups, dedicated hosting, custom SLAs, IT security reviews, and penetration testing. A process for reporting security incidents and a public security report are available. View security report.

Performance & Metrics

What should I know about Hygraph's product performance?

Hygraph leverages state-of-the-art caching and robust edge services for low latency and high read-throughput. Endpoints are deployed close to users worldwide, ensuring rapid content delivery and improved user experience. Customers have reported 7X higher content velocity, 125% traffic growth, and support for 40+ global markets. See performance details.

Customer Proof

Who are some of Hygraph's customers?

Hygraph is trusted by leading brands such as Sennheiser, HolidayCheck, Ancestry, JDE, Dr. Oetker, Ashley Furniture, Lindex, Hairhouse, Komax, Shure, Stobag, Burrow, G2I, Epic Games, Bandai Namco, Gamescom, Leo Vegas, Codecentric, Voi, and Clayton Homes. See customer stories.

Meet Hygraph AI Agents - Your Autonomous Teammates

React Suspense - A complete guide

This article explains how to use React Suspense to build smoother, faster, and more user-friendly React applications.
Joel Olawanle

Written by Joel 

Jun 24, 2024
React Suspense - A complete guide

The React team regularly releases new features to help make our applications more efficient and manageable. One such feature is React Suspense.

By the end of this article, you'll understand how to use React Suspense to build smoother, faster, and more user-friendly React applications.

#What is React Suspense, and how does it work?

React Suspense is a built-in feature that simplifies managing asynchronous operations in your React applications.

Unlike data-fetching libraries like Axios or state management tools like Redux, Suspense focuses solely on managing what is displayed while your components wait for asynchronous tasks to complete.

#How React Suspense works

When React encounters a Suspense component, it checks if any child components are waiting for a promise to resolve. If so, React "suspends" the rendering of those components and displays a fallback UI, such as a loading spinner or message, until the promise is resolved.

Here's an example to illustrate how Suspense works:

<Suspense fallback={<div>Loading books...</div>}>
<Books />
</Suspense>

In this code snippet, until the data for Books is ready, the Suspense component displays a fallback UI, in this case, a loading message. This clarifies to the user that the content is being fetched, providing a more seamless experience.

The fallback UI can be a paragraph, a component, or anything you prefer.

How it works with server-side rendering

React Suspense also enhances server-side rendering (SSR) by allowing you to render parts of your application progressively.

With SSR, you can use renderToPipeableStream to load essential parts of your page first and progressively load the remaining parts as they become available. Suspense manages the fallbacks during this process, improving performance, user experience, and SEO.

#Data fetching patterns in React

When a React component needs data from an API, there are three common data fetching patterns: fetch on render, fetch then render, and render as you fetch (which is what React Suspense facilitates). Each pattern has its strengths and weaknesses.

Let's explore these patterns with examples to understand their nuances better.

Fetch on render

In this approach, the network request is triggered inside the component after it has mounted. This straightforward pattern can lead to performance issues, especially with nested components making similar requests.

const UserProfile = () => {
const [user, setUser] = useState(null);
useEffect(() => {
fetch('/api/user')
.then(response => response.json())
.then(data => setUser(data));
}, []);
if (!user) return <p>Loading user profile...</p>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);
};

In this example, the fetch request is triggered in the useEffect hook after the component mounts. The loading state is managed by checking if the user data is available.

This approach can lead to a network waterfall effect, where each subsequent component waits for the previous one to fetch data, causing delays.

Fetch then render

The fetch-then-render approach initiates the network request before the component mounts, ensuring data is available as soon as the component renders.

This pattern helps avoid the network waterfall problem seen in the on-render approach.

const fetchUserData = () => {
return fetch('/api/user')
.then(response => response.json());
};
const App = () => {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUserData().then(data => setUser(data));
}, []);
if (!user) return <p>Loading user data...</p>;
return (
<div>
<UserProfile user={user} />
</div>
);
};
const UserProfile = ({ user }) => (
<div>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);

In this example, the fetchUserData function is called before the component mounts, and the data is set in the useEffect hook. The loading state is managed similarly by checking if the user data is available.

This method starts fetching early but still waits for all promises to be resolved before rendering useful data, which can lead to delays if one request is slow.

Render as you fetch

React Suspense introduces the render-as-you-fetch pattern, allowing components to render immediately after initiating a network request.

This improves user experience by rendering UI elements as soon as data is available, without waiting for all data to be fetched.

const fetchUserData = () => {
let data;
let promise = fetch('/api/user')
.then(response => response.json())
.then(json => { data = json });
return {
read() {
if (!data) {
throw promise;
}
return data;
}
};
};
const resource = fetchUserData();
const App = () => (
<Suspense fallback={<p>Loading user profile...</p>}>
<UserProfile />
</Suspense>
);
const UserProfile = () => {
const user = resource.read();
return (
<div>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);
};

In this example, the fetchUserData function starts fetching data immediately and returns an object with a read method. The read method throws a promise if the data isn't ready, which triggers Suspense to show the fallback UI. Once available, read returns the data, and the component renders it.

This pattern allows each component to manage its loading state independently, reducing wait times and improving the application's overall responsiveness.

#Use cases of Suspense

React Suspense can significantly enhance your applications' performance and user experience. Here are some practical use cases where Suspense shines:

1. Data fetching

One of the primary use cases of Suspense is managing data fetching in your applications. Using Suspense, you can display a loading state while fetching data from an API, providing a smoother user experience.

For example, the code below shows how the DataComponent fetches data and displays a loading message until the data is available.

const fetchData = () => {
let data;
let promise = fetch('/api/data')
.then(response => response.json())
.then(json => { data = json });
return {
read() {
if (!data) {
throw promise;
}
return data;
}
};
};
const resource = fetchData();
const App = () => (
<Suspense fallback={<p>Loading data...</p>}>
<DataComponent />
</Suspense>
);
const DataComponent = () => {
const data = resource.read();
return (
<div>
<h1>Data: {data.value}</h1>
</div>
);
};

The fetchData function initiates a fetch request and returns an object with a read method. If the data isn't ready, the read method throws a promise, which tells Suspense to display the fallback UI ("Loading data..."). Once available, read returns the data, and DataComponent renders it.

2. Lazy loading components

Suspense works seamlessly with React's lazy() function to load components only when needed, reducing your application's initial load time. This is especially useful for large applications where not all components are required immediately.

For example, here is a LazyComponent that is dynamically imported and lazy-loaded using React.lazy():

const LazyComponent = React.lazy(() => import('./LazyComponent'));
const App = () => (
<Suspense fallback={<p>Loading component...</p>}>
<LazyComponent />
</Suspense>
);

In this code, the <Suspense> component specifies a fallback message ("Loading component...") to display while the LazyComponent is being fetched and loaded.

3. Handling multiple asynchronous operations

Suspense can manage multiple asynchronous operations, ensuring that each part of the UI displays its loading state independently. This is useful in scenarios where different parts of the application fetch data from different sources.

const fetchUserData = () => {
let data;
let promise = fetch('/api/user')
.then(response => response.json())
.then(json => { data = json });
return {
read() {
if (!data) {
throw promise;
}
return data;
}
};
};
const fetchPostsData = () => {
let data;
let promise = fetch('/api/posts')
.then(response => response.json())
.then(json => { data = json });
return {
read() {
if (!data) {
throw promise;
}
return data;
}
};
};
const userResource = fetchUserData();
const postsResource = fetchPostsData();
const App = () => (
<div>
<Suspense fallback={<p>Loading user...</p>}>
<UserProfile />
</Suspense>
<Suspense fallback={<p>Loading posts...</p>}>
<Posts />
</Suspense>
</div>
);
const UserProfile = () => {
const user = userResource.read();
return (
<div>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);
};
const Posts = () => {
const posts = postsResource.read();
return (
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
};

In this code, there are two asynchronous operations: fetching user data and fetching posts data. Each fetch function returns an object with a read method that throws the promise if the data isn't ready.

The App component uses two <Suspense> components, each with its own fallback UI ("Loading user..." and "Loading posts..."). This setup allows the UserProfile and Posts components to manage their loading states independently, improving the application’s overall responsiveness.

You can also nest <Suspense> components to manage rendering order with Suspense:

const App = () => (
<div>
<Suspense fallback={<p>Loading user profile...</p>}>
<UserProfile />
<Suspense fallback={<p>Loading posts...</p>}>
<Posts />
</Suspense>
</Suspense>
</div>
);

This way, the outer <Suspense> component wraps the UserProfile component, displaying a fallback message ("Loading user profile...") while fetching user profile data, ensuring its details are shown first. Inside this outer <Suspense>, another <Suspense> wraps the Posts component with its fallback message ("Loading posts..."), ensuring posts details render only after the user profile details are available.

This setup effectively manages loading states. It displays the outer fallback message until user profile data is fetched and then handles the post data loading state with the nested fallback message.

4. Server-side rendering (SSR)

Suspense can improve SSR by allowing you to specify which parts of the app should be rendered on the server and which should wait until the client has more data. This can significantly enhance the performance and SEO of your web application.

For example, the code below shows an App component that uses <Suspense> to specify a fallback UI ("Loading...") while the MainComponent is being loaded.

import { renderToPipeableStream } from 'react-dom/server';
const App = () => (
<Suspense fallback={<p>Loading...</p>}>
<MainComponent />
</Suspense>
);
// Server-side rendering logic
const { pipe } = renderToPipeableStream(<App />);

The renderToPipeableStream function from react-dom/server handles the server-side rendering, ensuring that the initial HTML sent to the client is rendered quickly and additional data is loaded progressively.

#How to use React Suspense

So far, we've gone over how React Suspense works and explored various scenarios with code examples. Now, let's apply what we've learned to a live project.

For this quick demo, we'll fetch blog posts from Hygraph (a headless CMS that leverages GraphQL to serve content to your applications) into a React application (styled with Tailwind CSS) and use Suspense to display skeleton post animations until the posts are loaded.

Step 1: Clone a Hygraph project

First, log in to your Hygraph dashboard and clone the Hygraph “Basic Blog" starter project. You can also choose any project from the marketplace that suits your needs.

Next, go to the Project settings page, navigate to Endpoints, and copy the High-Performance Content API endpoint. We'll use this endpoint to make API requests in our React project.

Step 2: Set up data fetching logic

When building a React application, especially one that deals with asynchronous data fetching, it's essential to manage the state of your data requests efficiently.

To do this, handle asynchronous and data-fetching operations in two files within the api directory. This separation of concerns makes our code easier to read, test, and maintain. It also allows us to reuse the data-fetching logic across multiple components, promoting code reusability.

In your React project, create a folder named api in the root directory. This folder will contain the files for handling data fetching and promise management.

Create two files in the api folder: wrapPromise.js and fetchData.js.

wrapPromise.js

The wrapPromise.js file contains a function designed to handle the state of a promise, which is an object representing the eventual completion or failure of an asynchronous operation.

export default function wrapPromise(promise) {
let status = 'pending';
let result;
const suspender = promise.then(
(r) => {
status = 'success';
result = r;
},
(e) => {
status = 'error';
result = e;
}
);
return {
read() {
if (status === 'pending') {
throw suspender;
} else if (status === 'error') {
throw result;
} else if (status === 'success') {
return result;
}
},
};
}

The function tracks a promise's state using status ('pending', 'success', or 'error') and result (the resolved value or error). The suspender handles the promise's resolution or rejection, updating the status and result accordingly.

The returned object includes a read method that React's Suspense uses to check the promise's state: it throws the suspender if pending, the error if failed, or returns the result if successful.

fetchData.js

The fetchData.js file contains a function to perform the data fetching from the Hygraph GraphQL API.

import wrapPromise from './wrapPromise';
function fetchData(url, query) {
const promise = fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query }),
})
.then((res) => {
if (!res.ok) {
throw new Error(`HTTP error! Status: ${res.status}`);
}
return res.json();
})
.then((data) => data.data)
.catch((error) => {
console.error('Fetch error:', error);
throw error;
});
return wrapPromise(promise);
}
export default fetchData;

The fetchData function first imports wrapPromise to manage the state of fetched data. It then constructs a POST request using the provided API endpoint (url) and GraphQL query (query).

Any errors during the fetch are caught, logged, and rethrown. Finally, the function returns the promise wrapped by wrapPromise, enabling Suspense to handle its state.

Step 3: Create the React components

Now, let's create the React components that use Suspense to fetch and display data from Hygraph.

First, create a components folder inside the src folder. Within this components folder, create a file named Posts.jsx. This file handles making requests to the Hygraph API and displaying the fetched data.

Ensure you create a .env file at the root of your project and add the Hygraph API endpoint.

import fetchData from '../../api/fetchData';
const query = `
{
posts {
id
slug
title
excerpt
coverImage {
url
}
publishedAt
author {
name
picture {
url
}
}
}
}
`;
const resource = fetchData(import.meta.env.VITE_HYGRAPH_API, query);
const Posts = () => {
const { posts } = resource.read();
return (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8 mt-5">
{posts.map((currentPost) => (
<div className="relative h-[440px] mb-5" key={currentPost.id}>
<img
className="w-full h-52 object-cover rounded-lg"
src={currentPost.coverImage.url}
alt=""
/>
<h2 className="text-xl font-semibold my-4">{currentPost.title}</h2>
<p className="text-gray-600 mb-2">{currentPost.excerpt}</p>
<div className="flex justify-between items-center absolute bottom-0 w-full">
<div className="flex items-center">
<img
className="w-10 h-10 rounded-full object-cover mr-2"
src={currentPost.author?.picture.url}
alt=""
/>
<p className="text-sm text-gray-600">{currentPost.author?.name}</p>
</div>
<p className="text-sm text-gray-600">
{new Date(currentPost.publishedAt).toLocaleDateString('en-us', {
year: 'numeric',
month: 'short',
day: 'numeric',
})}
</p>
</div>
</div>
))}
</div>
);
};
export default Posts;

In the code above, we import the fetchData function from our previously created api folder. This function handles the data fetching process. We then define a GraphQL query to fetch posts.

Using the fetchData function, we pass the API endpoint (from the .env file) and the query to fetch the data. The function returns a resource object that we can use to read the data when it's ready.

In the Posts component, we call resource.read() to obtain the data. This method is designed to integrate with React Suspense, allowing our component to wait for the data to be fetched. Once the data is available, we map over the posts and render them in a grid layout, displaying each post's title, excerpt, cover image, and author information.

Next, in the App.jsx file, we import the Posts.jsx file and implement React Suspense:

import { Suspense } from 'react';
import Posts from './components/Posts';
import PostSkeleton from './components/PostSkeleton';
const App = () => {
return (
<div className="container mx-auto mt-24 px-5">
<div className="text-5xl font-semibold my-10">
<h1>Blog</h1>
</div>
<Suspense fallback={<PostSkeleton />}>
<Posts />
</Suspense>
</div>
);
};
export default App;

This setup ensures that users see a loading skeleton instead of a blank screen while the data is being fetched. Let’s create the skeleton.

In the components folder, create a PostSkeleton.jsx file and add the following code:

const PostSkeleton = () => {
return (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8 mt-5">
{[...Array(5)].map((_, index) => (
<div key={index} className="relative h-[400px] mb-5 animate-pulse">
<div className="w-full h-52 bg-gray-200 rounded-lg"></div>
<div className="h-6 bg-gray-200 rounded mt-4 w-3/4"></div>
<div className="h-4 bg-gray-200 rounded mt-2 w-5/6"></div>
<div className="h-10 bg-gray-200 rounded mt-2 w-5/6"></div>
<div className="flex justify-between items-center absolute bottom-0 w-full mt-4">
<div className="flex items-center">
<div className="w-10 h-10 bg-gray-200 rounded-full mr-2"></div>
<div className="h-4 bg-gray-200 rounded w-20"></div>
</div>
<div className="h-4 bg-gray-200 rounded w-16"></div>
</div>
</div>
))}
</div>
)
}
export default PostSkeleton

This component generates a grid of skeleton cards using the animate-pulse class for a loading animation. This skeleton structure helps maintain a consistent layout and provides a better user experience during data fetching.

When you load the React application, you notice the Skeleton displays until the data is fetched from Hygraph.

#Handling errors

We need to implement an error boundary to ensure our application handles errors. This component catches any errors during data fetching or rendering, preventing the entire app from crashing and providing a user-friendly error message.

First, create an ErrorBoundary.jsx file in the components folder. This component acts as a wrapper around other components, catching errors in its child component tree.

import { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static defaultProps = {
fallback: <h1>Something went wrong.</h1>,
};
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.log(error, errorInfo);
}
render() {
if (this.state.hasError) {
return this.props.fallback;
}
return this.props.children;
}
}
export default ErrorBoundary;

Next, we must modify App.jsx to wrap the Suspense component with the ErrorBoundary. This setup ensures that the error boundary captures errors occurring during data fetching or rendering.

import { Suspense, lazy } from 'react';
import Posts from './components/Posts';
import PostSkeleton from './components/PostSkeleton';
import ErrorBoundary from './components/ErrorBoundary';
const App = () => {
return (
<div className="container mx-auto mt-24 px-5">
<div className="text-5xl font-semibold my-10">
<h1>Blog</h1>
</div>
<ErrorBoundary fallback={<div>Failed to fetch data!</div>}>
<Suspense fallback={<PostSkeleton />}>
<Posts />
</Suspense>
</ErrorBoundary>
</div>
);
};
export default App;

With this setup, our application can handle errors. For instance, if you tamper with the API URL in Posts.jsx or any other issue during data fetching, the error boundary catches the error and displays the message "Failed to fetch data!" instead of crashing the entire app.

This ensures a better user experience even when something goes wrong in the background.

#Wrapping up

React Suspense is a powerful tool that simplifies handling asynchronous operations in React. By leveraging Suspense, you can improve your applications' performance and user experience.

Don't forget to sign up for a free-forever developer account on Hygraph to explore more about integrating React with a headless CMS.

Blog Author

Joel Olawanle

Joel Olawanle

Joel Olawanle is a Frontend Engineer and Technical writer based in Nigeria who is interested in making the web accessible to everyone by always looking for ways to give back to the tech community. He has a love for community building and open source.

Share with others

Sign up for our newsletter!

Be the first to know about releases and industry news and insights.