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 pageshowhide
explore
- Rules of Hooks and the Lint Plugin5 questions
- useState5 questions
- useReducer5 questions
- useEffect and useLayoutEffect5 questions
- useRef and useImperativeHandle5 questions
- useContext4 questions
- useMemo and useCallback4 questions
- useTransition and useDeferredValue5 questions
- useSyncExternalStore and useId5 questions
- use() and Reading Resources4 questions
- Form and Action Hooks5 questions
questions
page 2 of 2React's useReducer returns a dispatch function. Is that function's identity stable across re-renders, and what does the guarantee let you do?
basics
~20 sYes. 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.
What does the third argument in React's useReducer(reducer, initialArg, init) do, and when is passing it worth it?
basics
~20 sThe 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.
What does useImperativeHandle(ref, createHandle, deps) do in a React component, and why expose a custom handle instead of the raw DOM node?
basics
~20 suseImperativeHandle 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.
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?
basics
~20 sIn 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) => ...).
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?
basics
~20 sA 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.
In React, what is the difference between writing `useState(buildInitialState())` and `useState(buildInitialState)`, and when does that difference matter?
basics
~20 sThe 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.
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?
basics
~20 sgetServerSnapshot 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.
In React, what three arguments does useSyncExternalStore take, what is each one required to do, and what does the hook return?
basics
~20 suseSyncExternalStore 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.
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?
basics
~20 suseActionState'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.
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?
basics
~20 sThe 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.
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?
basics
~20 sReact'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.
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?
basics
~20 sSuspect 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.
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?
basics
~20 sEffects 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.
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?
basics
~20 sReact 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.
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?
basics
~20 sRendering 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.
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.
basics
~20 sEvery 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.
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?
basics
~20 sgetSnapshot 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.
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?
basics
~20 sThe 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.
In React 19, what may a callback ref return, and how does returning it change the way React detaches the ref?
basics
~20 sA 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.
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?
basics
~20 sA 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).
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?
basics
~20 sCall 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.
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?
basics
~20 sThe 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.
showing 31–52 of 52