skip to content

Built-in Hooks

You will learn the built-in hook APIs React ships — what each one's signature actually promises, how call order binds a hook to its state slot, and where the dependency array does and does not do what you expect. Interviewers spend a large share of a React screen here because almost every real bug (stale closures, missing cleanup, tearing, useless memoization) starts as a misread hook contract.

part ofReactoverview, primer and where to startread it →
on this pageshow

explore

questions

page 2 of 2

React's useReducer returns a dispatch function. Is that function's identity stable across re-renders, and what does the guarantee let you do?

level: middleimportance: should knowfreq 50%

basics

~20 s

Yes. React guarantees the dispatch function returned by useReducer keeps the same identity for the component's whole lifetime, so it can be omitted from dependency arrays, passed to memoized children, and put in context without causing churn.

open as a page

What does the third argument in React's useReducer(reducer, initialArg, init) do, and when is passing it worth it?

level: middleimportance: should knowfreq 38%

basics

~20 s

The third argument is a lazy initializer: React sets the initial state to init(initialArg) instead of initialArg, calling it only when the component mounts. It avoids rebuilding expensive initial state on every render and gives you one named function that also serves a reset.

open as a page

What does useImperativeHandle(ref, createHandle, deps) do in a React component, and why expose a custom handle instead of the raw DOM node?

level: middleimportance: should knowfreq 40%

basics

~20 s

useImperativeHandle replaces what the parent's ref points at with the object your createHandle function returns. The parent then sees only the methods you chose to expose, instead of the underlying DOM node or anything else inside the child.

open as a page

In React 19, how does a parent attach a ref to the <input> inside your custom function component, and what did forwardRef have to do before React 19?

level: middleimportance: should knowfreq 55%

basics

~20 s

In React 19, ref is an ordinary prop: accept it alongside the other props and pass it to the inner <input>. Before React 19, function components dropped ref, so you had to wrap them in forwardRef((props, ref) => ...).

open as a page

In React 19, what happens when a promise read with `use()` rejects, and why can't you handle it by wrapping the `use()` call in try/catch?

level: middleimportance: should knowfreq 36%

basics

~20 s

A rejection is thrown out of the component during render, so the nearest error boundary above it renders its fallback. React does not support try/catch around use(), because that catch would also intercept the throw React uses to signal suspension.

open as a page

In React, what is the difference between writing `useState(buildInitialState())` and `useState(buildInitialState)`, and when does that difference matter?

level: middleimportance: should knowfreq 52%

basics

~20 s

The first form calls buildInitialState on every render and throws the result away after the first. The second passes the function itself, so React calls it only during the initial render. That lazy form matters when the computation is expensive.

open as a page

When is the third argument to React's useSyncExternalStore, getServerSnapshot, required, what does it have to return, and what happens if you leave it out?

level: middleimportance: should knowfreq 30%

basics

~20 s

getServerSnapshot is required whenever the component is server-rendered. React calls it on the server and again for the initial hydration render, so it must return a value available without browser APIs and identical on both sides. Omitting it makes React throw during server rendering.

open as a page

In React, what three arguments does useSyncExternalStore take, what is each one required to do, and what does the hook return?

level: middleimportance: should knowfreq 45%

basics

~20 s

useSyncExternalStore takes subscribe (registers React's change callback and returns an unsubscribe function), getSnapshot (reads the store's current value), and an optional getServerSnapshot used during server rendering. It returns the current snapshot and re-renders the component when that snapshot changes.

open as a page

A React 19 form gets an isPending flag from useActionState and its submit button reads pending from useFormStatus. What does each of those flags actually track, and which one belongs in a shared SubmitButton component used across many forms?

level: seniorimportance: should knowfreq 38%

basics

~20 s

useActionState's isPending tracks that one specific action and is readable only where the hook is called. useFormStatus().pending tracks the enclosing form's submission and is readable from any descendant, so a shared SubmitButton reads that one and needs no props.

open as a page

What does the react-hooks/exhaustive-deps rule from eslint-plugin-react-hooks actually check, and what does it cost you to silence it with an eslint-disable comment?

level: seniorimportance: should knowfreq 56%

basics

~20 s

The exhaustive-deps rule compares the reactive values a hook's callback reads against the dependency array you wrote, reporting missing or unnecessary entries. Disabling it freezes that comparison forever, so later edits to the callback go unchecked.

open as a page

A React app throws "Invalid hook call. Hooks can only be called inside of the body of a function component" from a component in a locally linked library, even though that component's code follows the rules. How do you diagnose it?

level: seniorimportance: should knowfreq 42%

basics

~20 s

React's Invalid hook call error has three documented causes: a rules violation, mismatched React and renderer versions, or more than one copy of React in the bundle. With a linked local library the third is almost always it — the library resolves its own node_modules copy of React.

open as a page

A React app renders <AuthContext value={session}> near the root, yet a deep child's useContext(AuthContext) keeps returning the createContext default. The provider is definitely mounted above that child. What identity problem should you suspect, and how would you confirm it?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Suspect two different context objects. useContext matches providers by the identity of the object returned by createContext, so a duplicated module or a duplicated React copy gives the provider and the consumer separate objects, and the consumer's upward walk finds no match.

open as a page

Your React app is server-rendered, and a component calls useLayoutEffect. What happens to that effect during server rendering, and what would you do about it?

level: seniorimportance: should knowfreq 32%

basics

~20 s

Effects never run during server rendering, so useLayoutEffect is skipped and React logs a development warning about it. The server HTML carries the un-adjusted layout, and the correction happens only after hydration on the client.

open as a page

In React, why is const socket = useMemo(() => new WebSocket(url), [url]) the wrong way to give a component one long-lived connection, and what would you do instead?

level: seniorimportance: should knowfreq 40%

basics

~20 s

React may discard a useMemo cache and re-run the factory, so that line can open extra sockets, and opening one during render is a side effect with no teardown. Create the socket in an effect keyed on url, hold it in a ref, and close it in the cleanup.

open as a page

In React, why is reading or writing ref.current during rendering unsafe, and what is the accepted exception for lazily creating an expensive ref value?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Rendering must be pure and repeatable: React may run a component twice, discard the result, or restart it. A ref is untracked mutable state, so render-phase reads can observe a value from a render nobody saw, and writes make the render impure. The one sanctioned exception is initialising a ref that is still null.

open as a page

A React 19 client component calls `const user = use(fetch('/api/user/' + id).then(r => r.json()))` directly in its render body. It fetches endlessly and React logs a warning about an uncached promise. Explain the mechanism and how you would supply the promise instead.

level: seniorimportance: should knowfreq 40%

basics

~20 s

Every render creates a brand-new pending promise, so the component suspends, resumes, renders again, and starts another request — an endless loop. React does not cache promises created during a client render; the promise must be created outside render and passed in.

open as a page

A React component subscribes to an external store with useSyncExternalStore, and its getSnapshot is written as `() => ({ items: store.items, total: store.items.length })`. The page freezes and React warns that the result of getSnapshot should be cached. What is going wrong, and how do you fix it?

level: seniorimportance: should knowfreq 35%

basics

~20 s

getSnapshot builds a new object on every call, so React's Object.is comparison of consecutive snapshots is never equal. React re-renders, reads again, sees another new object, and loops. Fix it by caching the snapshot object in the store and recomputing it only when the store is written.

open as a page

A colleague changes a React controlled input's handler to startTransition(() => setQuery(e.target.value)), and now typing feels laggy with characters appearing late. What is wrong, and what is the fix?

level: seniorimportance: should knowfreq 44%

basics

~20 s

The input's displayed text comes from that state, and the transition marked it non-urgent, so React may delay or restart the render that shows the typed character. React's rule is that transitions cannot control a text input. Keep the input's state urgent and defer only the expensive derived work.

open as a page

In React 19, what may a callback ref return, and how does returning it change the way React detaches the ref?

level: middleimportance: nice to knowfreq 30%

basics

~20 s

A React 19 callback ref may return a cleanup function. When it does, React runs that cleanup on detach instead of calling the callback a second time with null, giving refs the same attach/cleanup shape that effects already have.

open as a page

A React component holds a callback in state with `const [handler, setHandler] = useState(() => defaultHandler)`. A later call to `setHandler(nextHandler)`, where `nextHandler` is also a function, leaves `handler` holding something unexpected. Why, and what should be written instead?

level: middleimportance: nice to knowfreq 26%

basics

~20 s

A function argument means updater, not value. React calls nextHandler with the current state and stores whatever it returns, so the state becomes that return value. Store a function by wrapping it: setHandler(() => nextHandler).

open as a page

A React form component renders three labelled inputs that each need their own id. Do you call useId three times, and how do you derive the ids?

level: middleimportance: nice to knowfreq 25%

basics

~20 s

Call useId once and append a suffix per field, such as ${id}-email and ${id}-name. Three separate calls also work, but one call plus suffixes scales to any number of related attributes and keeps the shared prefix visible in the markup.

open as a page

React exports startTransition as a standalone function as well as returning one from useTransition(). What is different about the standalone version, and when would you use it?

level: middleimportance: nice to knowfreq 32%

basics

~20 s

The standalone startTransition marks updates non-urgent exactly like the one from useTransition, but gives you no isPending flag. Because it is a plain import rather than a hook, it can be called outside components — in module-level code, store logic, or event callbacks where hooks are illegal.

open as a page

showing 31–52 of 52