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 interface
interface 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 Promise
  • onSuccess - Callback fired when the result is successful (optional)

The returned result:

  • data - API successful response data
  • isLoading - Loading state
  • error - Error message
  • callRequest - 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!

Subscribe icon

Subscribe to our Newsletter

Sign up with your email address to receive latest posts and updates