useFetch Hook for Fetching API
February 15th, 2023
Share:
useFetch
is a generic custom hook that calls an API from a component and exposes an object containing the API response data, callRequest
method, loading, and error states.
The API request
const getPosts = async (): Promise<ApiResponse> => { const response = await fetch(URL);
if (!response.ok) { throw new Error(`Server error: ${response.status}`); }
return await response.json();};
The useFetch hook
interface UseFetchProps<T> { request: () => Promise<T>; onSuccess?: () => void;}
// T Generic is used for the response data interfaceinterface UseFetchOutput<T> { callRequest: () => void; data: T[]; error?: Error; isLoading?: boolean;}
function useFetch<T> = ({ request, onSuccess,}: UseFetchProps<T>): UseFetchOutput<T> => { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null);
// Wrap callRequest into the useCallback to prevent the re-define of the function on every re-render. // It will be re-defined only if the request or onSuccess props are changed. const callRequest = useCallback(async () => { setIsLoading(true); setError(null);
try { const response = await request(); setData(response?.data); if (onSuccess) onSuccess(); } catch (error) { setError(error?.message); } finally { setIsLoading(false); } }, [request, onSuccess]);
return { callRequest, data, error, isLoading };};
export default useFetch;
Props:
request
- API fetch method that returns PromiseonSuccess
- Callback fired when the result is successful (optional)
The returned result:
data
- API successful response dataisLoading
- Loading stateerror
- Error messagecallRequest
- Function handles state for loading, value, and error
Usage of useFetch
const Component: React.FC = () => { const { callRequest, data, isLoading } = useFetch<DataTypes>({ request: () => getPosts(), onSuccess: () => {...logic after success..} });
// Execute the callRequest after the first render useEffect(() => { callRequest(); }, []);
// Execute the callRequest after the first render and one of its dependency’s updates useEffect(() => { callRequest(); }, [dependency1, dependency2]);
// Execute the callRequest by clicking on the button const handleClick = () => { callRequest(); }
return (<button onClick={handleClick}>Send a request</button>);};
The useFetch
hook can be helpful if your web application has many API calls. It encapsulates common logic and helps to avoid code duplication for each API request.
We hope this article was helpful to you! Thanks for reading!