In this short tutorial, we explore how to set up a data fetching hook in a react application. This hook also exposes a refetch function in case you want to to call the API again after some operation.
Firstly, we set up fetchData function which is only responsible for making the request to the end point. This async function only takes of the data fetching and returns some parameters and will be used in our hook.
export const fetchData = async (fetchUrl, options) => {
try {
const response = await fetch(fetchUrl, options);
const data = await response.json();
return { data, error: null, message: "success" };
} catch (err) {
return { data: null, error: JSON.stringify(err), message: "error" };
}
};
Below we define the useFetchData hook. It is a react hook that returns the data or the error response from the API call. It also tracks the loading state and the refetch function allowing for data refetching for that API for instance after a delete or update operation.
// useFetchData.js
import { useState, useCallback, useEffect } from "react";
export const useFetchData = (fetchUrl, options) => {
// The data state is used to show the data for instance
const [data, setData] = useState([]);
// The loading state is used to show the loading spinner for instance
const [loading, setLoading] = useState(false);
// The error state is used to show the error message for instance
const [error, setError] = useState(null);
const [message, setMessage] = useState(null);
// The fetch/refetch function is used to refetch the data from the remote server.
const fn = useCallback(() => {
async function callFetchData() {
setLoading(true);
const { data, error, message } = await fetchData(fetchUrl, options);
setData(data);
setError(error);
setLoading(false);
setMessage(message);
}
callFetchData();
}, [fetchUrl, options]);
useEffect(() => {
fn();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return { data, error, loading, message, refetch: fn };
};
export default useFetchData;
We can use the hook in our components as follows:
function PostsPage() {
usePageTitle();
const { data, error, message, loading, refetch } = useFetchData(
"https://jsonplaceholder.typicode.com/posts"
);
const handleRefetch = () => {
refetch();
};
return (
<div>
{loading && <div>Loading...</div>}
{error && <div>{error}</div>}
{message && <div>{message}</div>}
{data && (
<div>
{data.map((post) => (
<div>{post.title}</div>
))}
</div>
)}
<button onClick={handleRefetch}> RefechData </button>
<h1>News Page</h1>
</div>
);
}
Written by: