React data fetching along with best practices
Ever felt like fetching data in React is trickier than making the perfect cup of coffee? One minute, everything’s smooth, and the next, you’re dealing with an endless loading spinner or a mystery error message. But don’t worry—everyone’s been there!
The truth is, once you learn some simple tricks and best practices, it’s not that hard. In this article, we’ll go through the basics and show you how to handle data fetching smoothly. Ready to make things easier? Let’s get started!
Setting up the initial useEffect() for data fetching
To fetch data, the useEffect
hook is the go-to solution. Here's a basic example of using fetch
inside a React component:
import React, { useState, useEffect } from 'react';
function BasicDataFetch() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('https://xyz.com/posts')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
setError(error.message);
setLoading(false);
});
}, []); // Empty dependency array ensures this runs only once
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<div>
<h2>Fetched Data</h2>
{data && data.map(post => <p key={post.id}>{post.title}</p>)}
</div>
);
}
export default BasicDataFetch;
What's happening here?
We manage three states—
data
,loading
, anderror
.useEffect
hook Fetches data when the component mounts ([]
dependency array).If an error occurs, it's caught and displayed.
We’re Showing loading, error, or the actual data depending on the state.
Best Practices for Data Fetching
When a user navigates away from a page while a fetch request is still ongoing, it can result in memory leaks or unwanted updates on unmounted components. This is where AbortController
comes in. It allows us to cancel the request if the component unmounts.
import React, { useState, useEffect } from 'react';
function FetchWithAbort() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController(); // Create an AbortController
const signal = controller.signal;
const fetchData = async () => {
try {
const response = await fetch('https://xyz.com/posts', { signal });
if (!response.ok) {
throw new Error('Failed to fetch data');
}
const result = await response.json();
setData(result);
} catch (err) {
if (err.name === 'AbortError') {
console.log('Fetch aborted');
} else {
setError(err.message);
}
} finally {
setLoading(false);
}
};
fetchData();
return () => {
controller.abort(); // Abort fetch when component unmounts
};
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<div>
<h2>Fetched Data with AbortController</h2>
{data && data.map(post => <p key={post.id}>{post.title}</p>)}
</div>
);
}
export default FetchWithAbort;
How AbortController
works:
An instance of
AbortController
(controller
) is created.The
signal
is passed to the fetch request.When the component unmounts,
controller.abort()
is called, canceling the fetch request.If the request is aborted, it’s handled gracefully without causing memory leaks.
Conclusion:
By following these best practices we’ll ensure that your React app handles data fetching smoothly and efficiently. Happy coding!
Subscribe to my newsletter
Read articles from Rohan Kumar Pandey directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Rohan Kumar Pandey
Rohan Kumar Pandey
Hey!👋🏽 Myself Rohan from Bengaluru. I'm a frontend developer at weweonbase. -🔭 I've worked in GWOC'21 as a Contributor in Front-end development. -🔭I've won Hacktoberfest'21 by making 4 valid contributions. -🔭I got selected to participate in Script Winter of Contributing. 🌱 Currently I'm learning Dev-ops fundamentals. 👯 I’m looking for opportunities and learning new skills during the process.