Skip to main content
Version: 1.x.x

useFetch


Introduction

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 Command is the minimum requirement for useFetch.

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


Initialization

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

How it works?

useFetch executes a command 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 ...
});

const onSubmit = async (values: Values) => {
submit({ data: values });
};

return (
<div>
{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>{data.map(user => <div>{user.name}</div>)}</div>}
</div>
);
};

Options

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

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

{
bounce: boolean;
bounceTime: number;
bounceType: debounce | throttle;
deepCompare: boolean | typeof isEqual;
dependencies: any[];
dependencyTracking: boolean;
disabled: boolean;
initialData: ClientResponseType<Response, Error> | null;
refresh: boolean;
refreshBlurred: boolean;
refreshOnBlur: boolean;
refreshOnFocus: boolean;
refreshOnReconnect: boolean;
refreshTime: number;
revalidateOnMount: boolean;
}


Returns

Returned values from this hook.

const values = useFetch(command);

{
data: null | T extends Command<infer D, any, any, any, any, any, any, any, any, any> ? D : never;
error: null | T extends Command<any, any, any, infer G, infer L, any, any, any, any, any> ? G | L : never;
loading: boolean;
retries: number;
status: null | number;
timestamp: null | Date;
setData: (data: ExtractResponse<T>, emitToCache?: boolean) => void;
setError: (error: ExtractError<T>, emitToCache?: boolean) => void;
setLoading: (loading: boolean, emitToHooks?: boolean) => void;
setRetries: (retries: number, emitToCache?: boolean) => void;
setStatus: (status: number | null, 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;
};
revalidate: (invalidateKey?: InvalidationKeyType | InvalidationKeyType[]) => void;
}