useFetch
The useFetch hook is your main tool for fetching and reading data from a server in React components. It integrates
seamlessly with Hyper Fetch's core systems, such as the Dispatcher and
Cache, to deliver a robust, reactive, and efficient data-fetching experience.
- Declarative data fetching: Provide a
Requestand let the hook manage the process. - Automatic state management: Handles
loading,error, anddatastates for you. - Built-in reactivity: Automatically re-fetches data when dependencies change.
- Lifecycle callbacks: Easily run side effects on success, error, or completion.
- Deep cache integration: Uses a central cache to avoid redundant requests and boost performance.
To send data to the server (such as creating, updating, or deleting resources), use the
useSubmithook instead.
Quick Start
To use useFetch, provide a prepared Request instance. The hook returns the current state of
that request, including the fetched data, loading status, and any error that may have occurred.
Dependencies
useFetch can automatically re-fetch data when its request or dependency array changes. Pass a dependency array in the
options object (the second argument). When any value in the array changes, the hook triggers a new request.
This is especially useful for fetching data based on props, state, or other dynamic values.
Event Handlers
To handle side effects such as notifications, logging, or triggering other actions, useFetch provides a set of event
handler hooks. This keeps your component's rendering logic clean and separates side effects from state management.
onSuccess: Fires when the request completes successfully. The callback receives the successresponse.onError: Fires when the request results in an error. The callback receives theerrorobject.onFinished: Fires when the request finishes, regardless of the outcome.
Download and Upload Progress
useFetch provides two event handlers for tracking download and upload progress:
onDownloadProgress: Fires when the request is downloading data.onUploadProgress: Fires when the request is uploading data.
Both handlers receive give you access to a ProgressType object containing crucial information about the request's
progress.
| Name | Type | Description |
|---|---|---|
| loaded | | Loaded size in bytes |
| progress | | Progress in percentage (0-100) |
| sizeLeft | | Size left in bytes |
| startTimestamp | | Start timestamp in milliseconds |
| timeLeft | | Time left in seconds (null if not available) |
| total | | Total size in bytes |
We are providing advanced progress tracking for both download and upload - with ETA, size left, total size, loaded size, and more.
Suspense Mode
useFetch supports React's Suspense for data loading out of the box.
When enabled, the hook throws a Promise while the request is loading, which is caught by the nearest <Suspense> boundary.
Once the request resolves, the component re-renders with data immediately available — no loading state needed.
import { Suspense } from "react";
import { useFetch } from "@hyper-fetch/react";
import { getUsers } from "./api/users";
function UsersList() {
const { data } = useFetch(getUsers, { suspense: true });
return (
<ul>
{data.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
function App() {
return (
<Suspense fallback={<p>Loading users...</p>}>
<UsersList />
</Suspense>
);
}
Suspense mode requires React 18 or later. You can combine it with <ErrorBoundary> components to handle error states
declaratively.
Keep Previous Data
By default, when the cache key changes (e.g. switching from one resource to another), useFetch clears the previous
state and shows a fresh loading cycle. This prevents stale data from one resource leaking into another.
You can control this behavior with the keepPreviousData option:
"auto"(default) — Clears state when URL params change (different resource), preserves state when only query params change (pagination/filtering)."preserve"— Always keeps previous data visible until new data arrives. Ideal for pagination and infinite scroll."clean"— Always resets state to initial values when cache key changes.
import { useFetch } from "@hyper-fetch/react";
import { getUsers } from "./api/users";
function UsersList() {
const [page, setPage] = useState(1);
const { data, loading } = useFetch(getUsers.setQueryParams({ page }), {
keepPreviousData: "preserve",
});
return (
<div>
<Table data={data} loading={loading} />
<button type="button" onClick={() => setPage((p) => p + 1)}>
Next Page
</button>
</div>
);
}
Clear State
The clearState method resets all hook state (data, error, status, extra, timestamps) back to initial values.
This is useful when you need to manually reset the UI, for example after a user action or before navigating away.
import { useFetch } from "@hyper-fetch/react";
import { getUsers } from "./api/users";
function UsersList() {
const { data, error, clearState, refetch } = useFetch(getUsers);
const handleReset = () => {
clearState();
refetch();
};
return (
<div>
{data && <Table data={data} />}
{error && <p>Something went wrong</p>}
<button type="button" onClick={handleReset}>
Reset & Reload
</button>
</div>
);
}
Options
Customize the behavior of useFetch by passing an options object as the second argument.
const { ... } = useFetch(request, {
disabled: false,
dependencies: [],
revalidate: true,
// ... and more
});
Below is a full list of available options.
| Name | Type | Description |
|---|---|---|
| bounce | | Enable/disable debouncing for often changing keys or refreshing, to limit requests to server. |
| deepCompare | | Deep comparison function for hook to check for equality in incoming data, to limit rerenders. |
| dependencies | | Refetch dependencies |
| dependencyTracking | | If
true
it will rerender only when values used by our component gets changed. Otherwise it will rerender on any change. |
| disabled | | Disable fetching |
| initialResponse | | If cache is empty we can use placeholder data. |
| keepPreviousData | | Controls what happens to the current state when the cache key changes (e.g. params or query params change).
|
| refetchBlurred | | Enable/disable data refresh if our tab is not focused(used by user at given time). |
| refetchOnBlur | | Enable/disable data refresh if user leaves current tab. |
| refetchOnFocus | | Enable/disable data refresh if user enters current tab. |
| refetchOnReconnect | | Enable/disable data refresh if network is restored. |
| refresh | | Enable/disable refresh data |
| refreshTime | | Refresh data interval time |
| revalidate | | If
true
it will refetch data in background no matter if we have it from cache. |
| suspense | | Enable React Suspense mode. When true, the hook throws a Promise while loading, which is caught by the nearest Suspense boundary. The component re-renders with data available once the request resolves. |
State and Methods
useFetch returns an object containing the request's state, helper methods, and event handlers.
const {
data,
error,
loading,
status,
refetch,
onSuccess,
// ... and more
} = useFetch(request);
Below is a full list of returned values.
| Name | Type | Description |
|---|---|---|
| data | | Request response data |
| error | | Request response error |
| extra | | Request additional response data |
| loading | | Request loading state |
| requestTimestamp | | Request response timestamp |
| responseTimestamp | | Request response timestamp |
| retries | | Request attempts |
| status | | Request status |
| success | | Information whether request succeeded |
| bounce | | Data related to current state of the bounce usage |
| clearState | | Reset all state fields to their initial values (data, error, status, extra → null, loading → false, etc.). |
| setData | | Action to set custom data. We can do it locally(inside hook state). If you need to update cache data use client.cache.update(). method. |
| setError | | Action to set custom error. We can do it locally(inside hook state). If you need to update cache data use client.cache.update() method. |
| setExtra | | Action to set custom additional data. We can do it locally(inside hook state). If you need to update cache data use client.cache.update() method. |
| setLoading | | Action to set custom loading. We can do it locally(inside hook state). If you need to update cache data use client.cache.update() method. |
| setRequestTimestamp | | Action to set custom timestamp. We can do it locally(inside hook state). If you need to update cache data use client.cache.update() method. |
| setResponseTimestamp | | Action to set custom timestamp. We can do it locally(inside hook state). If you need to update cache data use client.cache.update() method. |
| setRetries | | Action to set custom retries count. We can do it locally(inside hook state). If you need to update cache data use client.cache.update() method. |
| setStatus | | Action to set custom status. We can do it locally(inside hook state). If you need to turn on loading for all listening hooks use client.requestManager.events.emitLoading() method. |
| setSuccess | | Action to set custom success. We can do it locally(inside hook state). If you need to update cache data use client.cache.update() method. |
| abort | | Callback that allows canceling ongoing requests from the given queryKey. |
| onAbort | | Helper hook listening on aborting of requests. Includes
mutationContext
when
setOptimistic
is configured. |
| onDownloadProgress | | Helper hook listening on download progress ETA. |
| onError | | Helper hook listening on error response. Includes
mutationContext
when
setOptimistic
is configured. |
| onFinished | | Helper hook listening on any response. Includes
mutationContext
when
setOptimistic
is configured. |
| onOfflineError | | Helper hook listening on request going into offline awaiting for network connection to be restored. |
| onRequestStart | | Helper hook listening on request start. |
| onResponseStart | | Helper hook listening on response start(before we receive all data from server). |
| onSuccess | | Helper hook listening on success response. Includes
mutationContext
when
setOptimistic
is configured. |
| onUploadProgress | | Helper hook listening on upload progress ETA. |
| refetch | | Refetch current request |
