Interview Q&A / React

IntermediateQuick answer1 min readUpdated 3 Oct 2026

How would you write a simple useFetch custom hook?

SHORT ANSWER

Keep data, loading and error in state, fetch inside an effect keyed on the URL, and ignore or abort stale responses in the cleanup. Return the three values so components stay free of fetching details.

Explain it simply

The same fetch, loading flag and error handling appear in many screens. A useFetch hook hides this behind one line: const { data, loading, error } = useFetch(url).

The tricky part is race conditions. If the URL changes quickly, the first slow response may arrive after the second and overwrite fresh data with stale data. An AbortController in the cleanup cancels the old request, so only the latest one can set state.

For production apps most teams use TanStack Query or SWR, which add caching and retries, but writing this once shows you understand the problem.

Example

jsx
function useFetch(url) {
  const [state, setState] = useState({ data: null, loading: true, error: null });

  useEffect(() => {
    const ctrl = new AbortController();
    setState({ data: null, loading: true, error: null });
    fetch(url, { signal: ctrl.signal })
      .then(r => { if (!r.ok) throw new Error(r.status); return r.json(); })
      .then(data => setState({ data, loading: false, error: null }))
      .catch(err => {
        if (err.name !== "AbortError") setState({ data: null, loading: false, error: err });
      });
    return () => ctrl.abort();
  }, [url]);

  return state;
}

What to say in the interview

"The hook keeps data, loading and error in state, fetches in an effect depending on the URL, and aborts the request in cleanup to avoid race conditions and updates after unmount. In real projects I would reach for a library like TanStack Query for caching and retries."

Common mistakes

  • Ignoring HTTP error status because fetch only rejects on network failure.
  • Not handling the abort error as a normal case.

#custom-hooks#data-fetching

Related questions

Practise more React questions

Test your recall with short answers, then return to the detailed explanations when you need context.

Open React quick answers →

Get new questions like this by email

One short email when something new and useful lands. No spam, unsubscribe in one tap.

By subscribing you agree to the Privacy Policy.