A strong hooks answer is a decision matrix, not a hook inventory. Explain useState vs useReducer, useRef vs state, useEffect vs derived logic, and when memoization or concurrent hooks actually earn their complexity.
Use this React interview question to rehearse a quick answer, common mistake, follow-up, and production pitfall.
Which React Hooks have you used, and when would you choose each?Frontend interview answer
This React interview question tests whether you can explain choose React Hooks: useState vs useReducer, useRef vs state, and effect trade-offs, connect it to production trade-offs, and handle common follow-up questions.
- choose React Hooks: useState vs useReducer, useRef vs state, and effect trade-offs explanation without falling back to memorized docs wording
- Hooks and State reasoning, edge cases, and production failure modes
- How you would answer the most likely React interview follow-up
Decision-first answer
A strong interview answer is not just “I used useState, useEffect, useRef...” It is “I choose hooks by job.” Use useState for simple local UI state, useReducer when many transitions belong to one state machine, useRef for mutable values that should not trigger renders, and useEffect only when syncing with something outside React.
Hook | Choose it when | Do not default to it for |
|---|---|---|
useState | Simple local UI state like inputs, toggles, and open/closed state | A multi-step state machine with many related transitions |
useReducer | State transitions depend on event types or several fields must change together | A single boolean or one text input |
useEffect | You must sync with an external system after render: fetches, subscriptions, timers, DOM APIs | Pure derived state or logic you can run directly in an event handler |
useRef | You need a DOM ref or a mutable value that should survive renders without rerendering the UI | Values the UI must render immediately |
useMemo | A derived value is expensive or you need a stable value for a memoized child | Wrapping every cheap calculation "just in case" |
useCallback | Callback identity matters for a memoized child or another dependency-sensitive hook | Every click handler in the app |
useContext | A value is already owned higher in the tree and many descendants need to read it | Replacing all state management or all prop drilling automatically |
useTransition / useDeferredValue | Typing or navigation must stay responsive while expensive updates happen in the background | Papering over unnecessary rerenders you should fix directly |
useLayoutEffect / useId | You must measure layout before paint or generate stable accessibility IDs | General side effects or random IDs |
High-signal trade-offs interviewers expect
useStatevsuseReducer: use reducer when transitions belong together and event names make the flow easier to reason about.useRefvs state: refs store mutable values without rerendering; state exists for values the UI should reflect.useEffect: reach for it when syncing with the outside world, not for values you can derive during render.useMemo/useCallback: optimize only when they protect measurable work or prop stability.
One component, different hook jobs
function ProductSearch({ products }) {
const [query, setQuery] = useState('');
const [filters, dispatch] = useReducer(filtersReducer, initialFilters);
const deferredQuery = useDeferredValue(query);
const inputRef = useRef<HTMLInputElement | null>(null);
const visibleProducts = useMemo(() => {
return filterProducts(products, deferredQuery, filters);
}, [products, deferredQuery, filters]);
useEffect(() => {
inputRef.current?.focus();
}, []);
return (
<>
<input
ref={inputRef}
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
<FiltersPanel filters={filters} dispatch={dispatch} />
<ResultsList products={visibleProducts} />
</>
);
}
This component uses useState because the search text is simple local UI state, useReducer because filter changes are event-driven and related, useDeferredValue because typing should stay urgent while large-list filtering can lag slightly, useMemo because filtering is derived and potentially expensive, and useRef plus useEffect because focusing an input is a DOM side effect rather than render state.
Custom hooks and Rules of Hooks
If you have built hooks such as useAuth, useDebouncedValue, or useProductSearch, mention them. That shows you can extract reusable stateful logic instead of bloating components. Also mention the Rules of Hooks: call hooks at the top level, and only call them from React components or other hooks, because React matches hook state by call order.
The strongest answer is a hook-choice framework: simple state vs reducer, ref vs state, effect vs derived logic, shared context vs local ownership, and memoization only when it protects real work. If you explain hooks that way, you sound like someone who can design components instead of just reciting APIs.
Use this as one explanation rep, then continue with the React interview questions cluster or a guided prep path.