Rooks
HooksExperimental Hooks

useRequest

Generic promise-request lifecycle hook with retries, polling, and mutation.

About

Manage a promise-returning service with manual or automatic execution, retries, debounce or throttle behavior, polling, mutation, and cancellation.

Example

import { useRequest } from "rooks/experimental";

async function fetchUser(id: string) {
  const response = await fetch(`/api/users/${id}`);
  return response.json() as Promise<{ name: string }>;
}

function Example({ userId }: { userId: string }) {
  const { data, loading, refresh } = useRequest(fetchUser, {
    defaultParams: [userId],
  });

  return (
    <div>
      <button onClick={refresh}>Refresh</button>
      <p>{loading ? "Loading..." : data?.name}</p>
    </div>
  );
}

Return value

PropertyTypeDescription
dataTData | undefinedLatest successful result, initialized from initialData.
errorError | nullLatest terminal request error.
loadingbooleanLoading state, optionally delayed by loadingDelay.
paramsTParams | undefinedParameters used by the latest execution.
run(...params: TParams) => voidSchedule/execute a request and discard its returned promise.
runAsync(...params: TParams) => Promise<TData>Schedule/execute a request and return its promise.
refresh() => voidRepeat the latest params, then defaultParams, or call with no arguments.
refreshAsync() => Promise<TData | undefined>Async form of refresh.
cancel() => voidInvalidate the active result and clear hook-managed timers.
mutate(value: SetStateAction<TData | undefined>) => voidReplace or derive data locally without calling the service.

Notes

  • useFetch remains the narrower fetch-specific alternative when you only need URL fetching.

Parameters

service is a required (...params: TParams) => Promise<TData>. The optional configuration object accepts:

OptionTypeDefaultEffect
manualbooleanfalseDisable automatic execution when true.
defaultParamsTParamsundefinedParameters for automatic execution/refresh; omission calls the service with no arguments.
readybooleantrueGate automatic execution.
initialDataTDataundefinedInitial data.
refreshDepsDependencyList[]Re-run automatically when an entry changes and the hook is ready.
debounceWaitnumberundefinedDebounce scheduled calls by this many milliseconds.
throttleWaitnumberundefinedThrottle scheduled calls by this many milliseconds.
loadingDelaynumber0Delay showing loading: true.
pollingIntervalnumberundefinedRe-run after success or terminal failure when positive.
pollingWhenHiddenbooleanfalseContinue scheduling while document.hidden.
retryCountnumber0Number of retries after the initial attempt.
retryIntervalnumber | ((attempt, error) => number)0Delay before each retry; attempts passed to the callback start at 1.
callbacksfunctionsundefinedonBefore, onSuccess, onError, and onFinally.

Positive debounceWait and throttleWait values are mutually exclusive; providing both throws during render.

Behavior and lifecycle

Only the newest execution may commit data, errors, loading state, or callbacks. Debounced calls with the same pending slot share its eventual result; throttled calls execute at the edge selected by the hook. Retry delays are cancellable, and polling pauses while the document is hidden before resuming on visibility. cancel rejects pending hook promises with Error("Request cancelled") and ignores a late service result, but it cannot abort the underlying service; pass cancellation into the service itself when network or CPU work must stop. Exceptions from lifecycle callbacks do not change request success, failure, or retry decisions.

Compatibility and accessibility

Automatic execution starts from an effect, so SSR returns initialData without invoking the service. Timer-based features require a browser-like window. Announce meaningful loading and errors in the UI, keep retry loops bounded for user-triggered work, and avoid polling endpoints while a page is hidden unless the product needs it.

On this page