Skip to main content

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.

The minimum requirement to use useFetch is to have a prepared Command.

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


Initialization

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

How it works?

useFetch executes the command when a component is mounted or when its dependencies array change. It uses dependency tracking to limit re-rendering and help with the performance. Under the hood the communication with the core systems is established by the events emitters. There are many helpful "helper hooks" that get returned from the hook like onSuccess, onError, onFinished and many more to help you handle interesting events in the request flow and lifecycle. We used this approach to not overload the base hook with the callbacks logic which cause low readability of the code and increase complication level. Thanks to this we can easily organize our code.

import { useFetch } from "@better-typed/react-hyper-fetch";
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 this hook provided as a second parameter.

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

Name Type Description
bounce boolean Enable/disable debouncing for often changing keys or refreshing, to limit requests to server.
bounceTime number How long it should bounce requests.
bounceType "debounce" | "throttle" Possibility to choose between debounce and throttle approaches
deepCompare boolean | query Deep comparison function for hook to check for equality in incoming data, to limit rerenders.
dependencies any[] Refetch dependencies
dependencyTracking boolean If `true` it will rerender only when values used by our component gets changed. Otherwise it will rerender on any change.
disabled boolean Disable fetching
initialData CacheValueType["data"] | null If cache is empty we can use placeholder data.
refresh boolean Enable/disable refresh data
refreshBlurred boolean Enable/disable data refresh if our tab is not focused(used by user at given time).
refreshOnBlur boolean Enable/disable data refresh if user leaves current tab.
refreshOnFocus boolean Enable/disable data refresh if user enters current tab.
refreshOnReconnect boolean Enable/disable data refresh if network is restored.
refreshTime number Refresh data interval time
revalidateOnMount boolean If `true` it will refetch data in background no matter if we have it from cache.


Returns

Returned values from this hook.

const values = useFetch(command);

Name Type Description
data null | ExtractResponse<T> Request response data
error null | ExtractError<T> Request response error
loading boolean Request loading state
retries number Request attempts
status null | number Request http status code
timestamp null | Date Request response timestamp
setData (data: ExtractResponse<T>, emitToCache: boolean) => void Action to set custom data. We can do it locally(inside hook state) or in cache(all related sources) with 'emitToCache' option.
setError (error: ExtractError<T>, emitToCache: boolean) => void Action to set custom error. We can do it locally(inside hook state) or in all hooks with 'emitToCache' option.
setLoading (loading: boolean, emitToHooks: boolean) => void Action to set custom loading. We can do it locally(inside hook state) or in cache(all related sources) with 'emitToCache' option
setRetries (retries: number, emitToCache: boolean) => void Action to set custom retries count. We can do it locally(inside hook state) or in cache(all related sources) with 'emitToCache' option
setStatus (status: number, emitToCache: boolean) => void Action to set custom status. We can do it locally(inside hook state) or in cache(all related sources) with 'emitToCache' option
setTimestamp (timestamp: Date, emitToCache: boolean) => void Action to set custom timestamp. We can do it locally(inside hook state) or in cache(all related sources) with 'emitToCache' option
abort () => void Callback which allows to cancel ongoing requests from given queueKey.
onAbort (callback: OnErrorCallbackType<T>) => void Helper hook listening on aborting of requests. Abort events are not triggering onError callbacks.
onDownloadProgress (callback: OnProgressCallbackType) => void Helper hook listening on download progress ETA. We can later match given requests by their id's or command instance which holds all data which is being transferred.
onError (callback: OnErrorCallbackType<T>) => void Helper hook listening on error response.
onFinished (callback: OnFinishedCallbackType<T>) => void Helper hook listening on any response.
onOfflineError (callback: OnErrorCallbackType<T>) => void Helper hook listening on request going into offline awaiting for network connection to be restored. It will not trigger onError when 'offline' mode is set on command.
onRequestStart (callback: OnStartCallbackType<T>) => void Helper hook listening on request start.
onResponseStart (callback: OnStartCallbackType<T>) => void Helper hook listening on response start(before we receive all data from server).
onSuccess (callback: OnSuccessCallbackType<T>) => void Helper hook listening on success response.
onUploadProgress (callback: OnProgressCallbackType) => void Helper hook listening on upload progress ETA. We can later match given requests by their id's or command instance which holds all data which is being transferred.
bounce {'{'} active: boolean, reset: () => void {'}'} Data related to current state of the bounce usage
revalidate (invalidateKey: string | RegExp | CommandInstance) => void Revalidate current command resource or pass custom key to trigger it by invalidationKey(Regex / cacheKey).