Skip to main content
Version: v8.0.0

useFetch

Read the API Reference »

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.

Purpose
  1. Declarative data fetching: Provide a Request and let the hook manage the process.
  2. Automatic state management: Handles loading, error, and data states for you.
  3. Built-in reactivity: Automatically re-fetches data when dependencies change.
  4. Lifecycle callbacks: Easily run side effects on success, error, or completion.
  5. 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 useSubmit hook 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.

Fetching a list of users
Request
Learn more about creating and configuring requests.

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.

Re-fetching on dependency change

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.

  1. onSuccess: Fires when the request completes successfully. The callback receives the success response.
  2. onError: Fires when the request results in an error. The callback receives the error object.
  3. onFinished: Fires when the request finishes, regardless of the outcome.
Using Event Handlers

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.

ProgressType
Name Type Description
loaded
number
Loaded size in bytes
progress
number
Progress in percentage (0-100)
sizeLeft
number
Size left in bytes
startTimestamp
number
Start timestamp in milliseconds
timeLeft
number | null
Time left in seconds (null if not available)
total
number
Total size in bytes

Rich progress tracking

We are providing advanced progress tracking for both download and upload - with ETA, size left, total size, loaded size, and more.

Using Download and Upload Progress

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.

Using Suspense
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>
);
}
React 18+ Required

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.
Pagination with keepPreviousData
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.

Using clearState
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.

UseFetchOptionsType
Name Type Description
bounce
boolean
Enable/disable debouncing for often changing keys or refreshing, to limit requests to server.
deepCompare
boolean | typeof isEqual
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
initialResponse
NullableType<Partial<ExtractAdapterResolvedType<R>>>
If cache is empty we can use placeholder data.
keepPreviousData
auto | preserve | clean
Controls what happens to the current state when the cache key changes (e.g. params or query params change).
  • "auto" (default) — Smart mode: 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.
  • "clean" — Always resets state to initial values when cache key changes.
refetchBlurred
boolean
Enable/disable data refresh if our tab is not focused(used by user at given time).
refetchOnBlur
boolean
Enable/disable data refresh if user leaves current tab.
refetchOnFocus
boolean
Enable/disable data refresh if user enters current tab.
refetchOnReconnect
boolean
Enable/disable data refresh if network is restored.
refresh
boolean
Enable/disable refresh data
refreshTime
number
Refresh data interval time
revalidate
boolean
If true it will refetch data in background no matter if we have it from cache.
suspense
boolean
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.

UseFetchOptionsType API Reference
Learn more about the useFetch hook.

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.

UseFetchReturnType
Name Type Description
data
null | ExtractResponseType<T>
Request response data
error
null | ExtractErrorType<T>
Request response error
extra
null | ExtractAdapterExtraType<ExtractAdapterType<T>>
Request additional response data
loading
boolean
Request loading state
requestTimestamp
null | Date
Request response timestamp
responseTimestamp
null | Date
Request response timestamp
retries
number
Request attempts
status
null | ExtractAdapterStatusType<ExtractAdapterType<T>> | null
Request status
success
boolean
Information whether request succeeded
bounce
{ active: boolean; reset: () => void }
Data related to current state of the bounce usage
clearState
() => void
Reset all state fields to their initial values (data, error, status, extra → null, loading → false, etc.).
setData
(data: CacheSetState<ExtractResponseType<T> | null>) => void
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
(error: CacheSetState<ExtractErrorType<T> | null>) => void
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
(extra: CacheSetState<ExtractAdapterExtraType<ExtractAdapterType<T>> | null>) => void
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
(loading: CacheSetState<boolean>) => void
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
(timestamp: CacheSetState<Date>) => void
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
(timestamp: CacheSetState<Date>) => void
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
(retries: CacheSetState<number>) => void
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
(status: CacheSetState<ExtractAdapterStatusType<ExtractAdapterType<T>>>) => void
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
(success: CacheSetState<boolean>) => void
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
() => void
Callback that allows canceling ongoing requests from the given queryKey.
onAbort
(callback: OnErrorCallbackType<T>) => void
Helper hook listening on aborting of requests. Includes mutationContext when setOptimistic is configured.
onDownloadProgress
(callback: OnProgressCallbackType) => void
Helper hook listening on download progress ETA.
onError
(callback: OnErrorCallbackType<T>) => void
Helper hook listening on error response. Includes mutationContext when setOptimistic is configured.
onFinished
(callback: OnFinishedCallbackType<T>) => void
Helper hook listening on any response. Includes mutationContext when setOptimistic is configured.
onOfflineError
(callback: OnErrorCallbackType<T>) => void
Helper hook listening on request going into offline awaiting for network connection to be restored.
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. Includes mutationContext when setOptimistic is configured.
onUploadProgress
(callback: OnProgressCallbackType) => void
Helper hook listening on upload progress ETA.
refetch
() => void
Refetch current request

useFetch API Reference
Learn more about the useFetch hook.

See More

Fetching data
Learn more about fetching data with useFetch.
useSubmit
Learn more about the useSubmit hook.
useCache
Learn more about the useCache hook.