Skip to content

Instantly share code, notes, and snippets.

@marco-souza
Created August 8, 2020 01:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marco-souza/79457d0b5ac97db6351ae120f726532b to your computer and use it in GitHub Desktop.
Save marco-souza/79457d0b5ac97db6351ae120f726532b to your computer and use it in GitHub Desktop.
JS/TS useFetch react hook
import { useState, useEffect } from "react";
export enum FetchStatus {
IDLE,
LOADING,
SUCCESS,
FAILURE,
CANCELED,
}
export interface UseFetchState<R> {
response?: R;
error?: Error;
status: FetchStatus;
}
export function useFetch<Res>(url: RequestInfo, options?: RequestInit): UseFetchState<Res> {
const [response, setResponse] = useState<Res>()
const [error, setError] = useState<Error>();
const [status, setStatus] = useState<FetchStatus>(FetchStatus.IDLE);
useEffect(() => {
const abortController = new AbortController();
const signal = abortController.signal;
const doFetch = async (): Promise<void> => {
setStatus(FetchStatus.LOADING);
try {
const res = await fetch(url, options);
if (!res.ok) throw new Error(res.statusText);
if (signal.aborted) return setStatus(FetchStatus.CANCELED);
const json: Res = await res.json();
setResponse(json);
setStatus(FetchStatus.SUCCESS);
} catch (e) {
if (signal.aborted) return setStatus(FetchStatus.CANCELED);
setError(e);
setStatus(FetchStatus.FAILURE);
}
};
doFetch();
return () => {
abortController.abort();
};
}, []);
return { response, error, status };
}
export default useFetch;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment