useFetch is a reusable custom React Hook for loading a resource from a URL. It keeps fetching logic outside components and returns data, status, and error so the component can focus on rendering. section 9.1 section 9.5
The hook exposes a small state machine:
- Starts with status "idle", undefined data, and a null error. section 9.5.1
- Sets status to "loading", clears previous data, and resets the error before each request. section 9.5.1
- Stores the response and sets "success", or stores a JavaScript error and sets "error". section 9.5.1
- Repeats the effect when the URL changes and prevents stale requests from updating state after cleanup. section 9.5.1
Rendering fetched bookables
A component can destructure the result, default undefined data to an empty array, and select its UI from status: show an error message for "error", a spinner for "loading", or the bookables for "success". The same pattern supports user lists and other resources. section 9.5.2
Listing 9.12 The useFetch hook
import {useEffect, useState} from "react";
import getData from "./api";
export default function useFetch (url) {
const [data, setData] = useState();
const [error, setError] = useState(null);
const [status, setStatus] = useState("idle"); #1
useEffect(() => {
let doUpdate = true;
setStatus("loading"); #2
setData(undefined);
setError(null);
getData(url)
.then(data => {
if (doUpdate) {
setData(data);
setStatus("success"); #3
}
})
.catch(error => {
if (doUpdate) {
setError(error); #4
setStatus("error");
}
});
return () => doUpdate = false;
}, [url]);
return {data, status, error};
}
#1 Set the initial status as “idle.”
#2 Just before sending a request, set the status to “loading.”
#3 If the data comes back successfully, set the status to “success.”
#4 If there was a problem fetching, set the status to “error.”
The complete listing shows the hook’s useState values, effect lifecycle, request guard, status transitions, and returned object. section 9.5.1
