Skip to main content
Version: 5.x.x



This hook is created to retrieve data from the server. It uses the Fetch Dispatcher to handle requests and the Cache to manage the overall state of the data.

A prepared Request is the minimum requirement for useFetch.

If you intend to mutate data stored on the server, we recommend choosing the useSubmit hook.


const { data, error, loading, onSuccess, onError, onFinished } = useFetch(getUsers);

How it works?

useFetch executes a request when a component is mounted or when its dependencies array changes. It uses dependency tracking to limit re-rendering and help with performance.

Under the hood, communication with the core systems is established by event emitters. There are many "helper hooks" that get returned from the hook, like onSuccess, onError, and onFinished (among others). They will help you handle various events in the request flow and lifecycle.

We used this approach to avoid overloading the base hook with callback logic, which causes low code readability and increases complexity.

import { useFetch } from "@hyper-fetch/react";
import { getUsers } from "server";

const UsersListPage: React.FC = () => {
const { data, error, loading, onSuccess, onError, onFinished } = useFetch(getUsers);

onSuccess(({ response }) => {
console.log(response); // [ User, User, User ]

onError(({ response }) => {
console.log(response); // { message: string }

onFinished(({ response }) => {
const [payload, error, status] = response;
console.log(payload); // [ User, User, User ] | null
console.log(error); // { message: string } | null
console.log(status); // 200 / 400 / 404 / 500 ...

return (
{loading && <Loader>}
{!loading && error && <Alert severity="error">{error.error_message}</Alert>}
{!loading && !error && !data.length && <div>List is empty</div>}
{!loading && !error && data.length && <div>{ => <div>{}</div>)}</div>}


Configuration options for useFetch must be provided as the second parameter.

const { ... } = useFetch(request, options)

bounce: boolean;
deepCompare: boolean | typeof isEqual;
dependencies: any[];
dependencyTracking: boolean;
disabled: boolean;
initialData: T | NegativeTypes;
refetchBlurred: boolean;
refetchOnBlur: boolean;
refetchOnFocus: boolean;
refetchOnReconnect: boolean;
refresh: boolean;
refreshTime: number;
revalidate: boolean;
...params2: {bounceTime:number,bounceType:debounce} | {bounceTime:number,bounceTimeout:number,bounceType:throttle};


Returned values from this hook.

const values = useFetch(request);

data: null | T extends Request<infer D, any, any, any, any, any, any, any, any, any> ? D : never;
error: null | T extends Request<any, any, any, infer G, infer L, any, any, any, any, any> ? G | L : never;
extra: T extends AdapterType<any, any, any, infer A, any> ? A : never;
loading: boolean;
retries: number;
status: T extends AdapterType<any, any, infer S, any, any> ? S : never;
success: boolean;
timestamp: null | Date;
setData: (data: ExtractResponseType<T>, emitToCache?: boolean) => void;
setError: (error: ExtractErrorType<T>, emitToCache?: boolean) => void;
setExtra: (extra: ExtractAdapterExtraType<ExtractAdapterType<T>>, emitToCache?: boolean) => void;
setLoading: (loading: boolean, emitToHooks?: boolean) => void;
setRetries: (retries: number, emitToCache?: boolean) => void;
setStatus: (status: ExtractAdapterStatusType<ExtractAdapterType<T>>, emitToCache?: boolean) => void;
setSuccess: (success: boolean, emitToCache?: boolean) => void;
setTimestamp: (timestamp: Date, emitToCache?: boolean) => void;
abort: () => void;
onAbort: (callback: OnErrorCallbackType<T>) => void;
onDownloadProgress: (callback: OnProgressCallbackType) => void;
onError: (callback: OnErrorCallbackType<T>) => void;
onFinished: (callback: OnFinishedCallbackType<T>) => void;
onOfflineError: (callback: OnErrorCallbackType<T>) => void;
onRequestStart: (callback: OnStartCallbackType<T>) => void;
onResponseStart: (callback: OnStartCallbackType<T>) => void;
onSuccess: (callback: OnSuccessCallbackType<T>) => void;
onUploadProgress: (callback: OnProgressCallbackType) => void;
bounce: {
active: boolean;
reset: () => void;
refetch: (invalidateKey?: InvalidationKeyType | InvalidationKeyType[]) => void;