Traditional Data Fetching Techniques
Fetch on Render:
Data fetching starts only when component is being rendered on the page.
This is the most widely used data fetching method, usually used with useState to manage loading state.
Key features and concepts:
- Data fetching starts after the page is being rendered.
- useState is used to manage loading and error state.
- Network waterfall is longer than Fetch on Render.
Disadvantages:
- Only one fetch call happen at time which severely damages website performance.
- Error handling becomes difficult.
- Child component’s API call will start only after the completion of parent component.
- This method is not SEO friendly.
Example: To demonsrtate using Fetch on Render technique from the component.
import { useState, useEffect } from 'react';
import "./App.css";
function App() {
const [data, setData] = useState<{ title: string }[]>([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
(async () => {
setIsLoading(true);
const resData: { title: string }[] =
await fetch("https://jsonplaceholder.typicode.com/todos")
.then(res => res.json());
setData(resData);
setIsLoading(false);
})()
}, [])
return (
<main>
{isLoading && <div>Loading...</div>}
{!isLoading && data.map((item, index) => (
<div key={index}>
{item.title}
</div>
))}
</main>
);
}
export default App;
Fetch then Render
Data is fetched before rendering the component outside the react component.
Key features and concepts:
- Rendering starts after all the data is fetched.
- useState is used to manage loading and error state.
- Network waterfall is shorter than Fetch on Render.
Disadvantages:
- Website performance is impacted as only one API call can occur at a time.
- Child component’s API call will start only after the completion of parent component.
- Rendering will start after all the data fetching is completed.
Example: To demonsrtate creating a react component which is using Fetch then Render technique.
import { useState, useEffect } from 'react';
import "./App.css";
async function fetchTodo() {
const data: { title: string }[] =
await fetch("https://jsonplaceholder.typicode.com/todos")
.then(res => res.json());
return data
}
const allData = fetchTodo();
function App() {
const [data, setData] = useState<{ title: string }[]>([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
(async () => {
setIsLoading(true);
const resData = await allData;
setData(resData);
setIsLoading(false);
})()
}, [])
return (
<main>
{isLoading && <div>Loading...</div>}
{!isLoading && data.map((item, index) => (
<div key={index}>
{item.title}
</div>
))}
</main>
);
}
export default App;
How does Suspense help in Handling Asynchronous Operations in React ?
Suspense, first introduced in React 16, is a feature that aims to enhance the user experience by managing asynchronous operations. It simply lets you render a fallback UI decoratively while the child component is waiting for any asynchronous task to be completed.
Table of Content
- What is React Suspense?
- Project Initialisation
- Traditional Data Fetching Techniques
- How Suspense works?
- Use cases of React Suspense
- Suspense with Server Components in Next.js
- Conclusion