React Developer interview questions
100 real questions with model answers and explanations for Middle candidates.
See a React Developer resume example →Practice with flashcards
Spaced repetition · Hunter Pass
Questions
A component should calculate the same JSX from the same props, state, and context without causing side effects during render.
- Rendering may run more than once, be paused, or be abandoned, so network calls and subscriptions do not belong in the component body.
- Event handlers perform user-triggered effects, while useEffect synchronizes with external systems after a commit.
- Local mutation of values created during the current render is fine, but mutating shared objects makes output order-dependent.
Why interviewers ask this: The interviewer checks whether the candidate understands purity as a requirement of React's repeatable rendering model.
Each render sees a fixed snapshot of state, and setting state schedules a later render rather than changing that snapshot.
- An event handler keeps the state values captured by the render that created it.
- Multiple reads after setState in the same handler still return the old snapshot.
- Code that needs the next value based on the previous one should use a functional state updater.
Why interviewers ask this: A strong answer connects snapshot semantics to event handlers and predictable state updates.
React associates Hook state with call order, so that order must remain stable across renders.
- Calling a Hook inside a condition, loop, or nested function can shift later Hook positions.
- The exception is not based on whether a branch usually runs; every possible render must preserve the order.
- Conditional behavior belongs inside the Hook callback or in a separately rendered component.
Why interviewers ask this: The interviewer evaluates whether the candidate understands the mechanism behind the Rules of Hooks.
Use a functional updater when the next state depends on the previous state.
- React passes the latest queued value to a function such as setCount(count => count + 1).
- This prevents several updates in one event from all using the same captured snapshot.
- It also reduces unnecessary dependencies when a memoized callback only needs state to calculate its replacement.
Why interviewers ask this: The interviewer checks whether the candidate can avoid stale snapshot errors in dependent updates.
useEffect synchronizes a component with an external system after React commits the UI.
- Dependencies are every reactive value read by the effect, including props, state, and functions declared in the component.
- React compares each dependency with Object.is and reruns the effect after a commit when one changes.
- An empty array means the effect uses no reactive values, not that dependencies may be omitted for convenience.
Why interviewers ask this: A strong answer frames effects as synchronization and treats dependencies as derived from code rather than manually chosen triggers.
Cleanup must undo the subscription, timer, connection, or other external work created by that effect's setup.
- React runs cleanup before rerunning an effect with changed dependencies and after unmounting.
- In development Strict Mode, an extra setup and cleanup cycle exposes code that cannot safely reconnect.
- Cleanup should use the same identifiers or handler references that setup registered.
Why interviewers ask this: The interviewer tests whether effects are designed as symmetric synchronization processes without leaked resources.
useLayoutEffect runs after DOM updates but before the browser paints, while useEffect normally runs after paint.
- Layout effects suit DOM measurement that must immediately influence the visible layout.
- Because they block painting, excessive work in useLayoutEffect hurts responsiveness.
- Prefer useEffect unless the user would otherwise see an incorrect intermediate frame.
Why interviewers ask this: The interviewer checks whether the candidate can justify the paint-blocking Hook instead of using it as a default.
useMemo caches a calculation result between renders while its dependencies remain equal, but it is a performance optimization rather than a semantic guarantee.
- React computes the function during render, so it must stay pure.
- The cache can be discarded for framework reasons, so correctness cannot depend on it.
- It is useful when an expensive calculation or stable derived value measurably avoids work.
Why interviewers ask this: A strong answer distinguishes optional memoization from persistent state or required program behavior.
useMemo can add comparison, memory, and code complexity when the cached calculation is cheap or its dependencies change frequently.
- Memoizing a primitive calculation rarely helps because passing the primitive already has stable value equality.
- One always-new dependency invalidates the cache on every render.
- Optimization should follow profiler evidence or a clear expensive path, not be applied to every expression.
Why interviewers ask this: The interviewer evaluates whether the candidate understands the cost model and avoids cargo-cult memoization.
useCallback memoizes a function reference, not the result produced when that function is called.
- React returns the previous function while all dependencies remain equal by Object.is.
- Stable callback identity matters when a memoized child receives it or another Hook depends on it.
- It does not stop creation of the inline function expression itself, and it does not make the callback execution cheaper.
Why interviewers ask this: The interviewer checks whether the candidate understands referential identity rather than describing useCallback as general function optimization.
useMemo caches a computed value, while useCallback caches the function reference itself.
- useMemo(() => value, deps) stores the returned value.
- useCallback(fn, deps) is conceptually equivalent to useMemo(() => fn, deps).
- Both are justified by identity-sensitive consumers or expensive work and require complete dependencies.
Why interviewers ask this: The interviewer evaluates whether the candidate can select the Hook based on what must remain referentially stable.
useRef stores a stable mutable object across renders and can also point to a DOM node managed by React.
- Updating ref.current does not trigger a render because a ref is outside React's visual state flow.
- DOM refs support imperative actions such as focus, selection, and measurement.
- A ref can hold values such as timer IDs when they are needed by handlers but not by rendering.
Why interviewers ask this: A strong answer covers both DOM access and non-visual persistent values without treating refs as replacement state.
Reading or mutating ref.current during render can make output depend on hidden mutable state and break render purity.
- React may invoke, restart, or discard renders, so render-time mutation has unreliable timing.
- Initialization behind a stable null check is a narrow accepted pattern when it always produces the same object.
- Normal ref reads and writes belong in effects or event handlers.
Why interviewers ask this: The interviewer checks whether the candidate respects concurrent-safe rendering rather than using refs as invisible variables.
A value should be state when changing it must update what the user sees, and a ref when it only supports imperative or bookkeeping logic.
- State schedules rendering and participates in React's snapshot model.
- Ref updates are immediate mutations that React does not observe for rendering.
- Duplicating the same source of truth in both state and a ref creates synchronization risk.
Why interviewers ask this: The interviewer evaluates whether the candidate chooses storage based on rendering requirements rather than convenience.
useContext reads the value from the closest matching provider above the calling component in the rendered tree.
- Providers are resolved by tree position, not by the file where components are declared.
- A provider returned by the same component cannot affect a useContext call earlier in that component.
- Without a provider, React returns the default value passed when the context was created.
Why interviewers ask this: The interviewer checks precise understanding of provider lookup and default values.
A consumer rerenders when its nearest provider receives a value that is not Object.is-equal to the previous value.
- React.memo does not block a fresh context value from reaching a consumer.
- A newly created object or function changes identity even when its contents look identical.
- Splitting unrelated data into separate contexts limits the number of consumers affected by each update.
Why interviewers ask this: A strong answer connects context propagation to value identity and rerender scope.
An inline object has a new reference on every provider render, so all consumers observe a changed context value.
- Memoize the object only when its fields and callback dependencies can remain stable.
- Separating state from actions or splitting contexts can reduce update fan-out more effectively.
- Provider optimization matters most for broad contexts with many frequently rendered consumers.
Why interviewers ask this: The interviewer evaluates whether the candidate understands provider value identity and avoids shallow fixes without considering context design.
useReducer centralizes state transitions when several related values change through a defined set of actions.
- A reducer receives the current state and an action and returns the next state.
- Dispatch describes what happened without exposing how every field must be updated.
- It is useful for complex local workflows, but it does not automatically make state global.
Why interviewers ask this: The interviewer checks whether the candidate understands reducers as a state-transition model rather than a global store feature.
A reducer should be pure, deterministic, and return a new state when a transition changes data.
- It must not mutate the existing state because React relies on identity to observe changes.
- Side effects such as requests, timers, and logging do not belong inside the reducer.
- Unknown actions should follow an explicit policy, commonly returning current state or throwing in development.
Why interviewers ask this: A strong answer identifies the reducer contract that keeps transitions replayable and testable.
useReducer is preferable when state fields form one transition model and many events update them together.
- It keeps valid transitions in one place and can prevent partial combinations of related updates.
- useState remains clearer for a few independent values with simple replacements.
- Reducer boilerplate is not justified only because an object has several properties.
Why interviewers ask this: The interviewer evaluates judgment about state complexity instead of assuming reducers are always more scalable.
Locked questions
- 21
What makes a function a custom Hook?
hooks - 22
Do two components calling the same custom Hook share its state?
componentshooks - 23
How should dependencies be handled inside a custom Hook?
hooksdependencies - 24
What is a stale closure in a React Hook?
reacthooksclosures - 25
What is reconciliation in React?
react - 26
How do component type and tree position affect state preservation?
components - 27
What role do keys play in React lists?
react - 28
Why are array indexes often poor React keys?
reactindexes - 29
How can a key be used outside a list to reset component state?
components - 30
What does the term virtual DOM mean in React?
reactdomvirtual-dom - 31
How do React's render and commit phases differ?
react - 32
What does React.memo do?
react - 33
Why do object and function props often defeat React.memo?
react - 34
What is a sound approach to React render optimization?
reactoptimization - 35
What is a controlled form input in React?
reactforms - 36
What is an uncontrolled form input, and when is it useful?
forms - 37
Why does React warn when an input switches between controlled and uncontrolled?
reactforms - 38
What problem does ref forwarding solve?
- 39
What does useImperativeHandle do?
- 40
How do React portals behave in the React tree and the DOM tree?
reactdom - 41
What is a React error boundary?
react - 42
Which errors are not caught by an error boundary?
react - 43
What does Suspense represent conceptually?
react - 44
How does Suspense boundary placement affect user experience?
react - 45
What does concurrent rendering mean in React 18?
reactconcurrency - 46
What does startTransition communicate to React?
communicationreact - 47
How does useTransition extend startTransition?
- 48
What is useDeferredValue for?
- 49
What changed about automatic batching in React 18?
reactbatch - 50
What does React Strict Mode reveal in development?
react - 51
How would you build a reusable modal component that remains accessible and composable?
components - 52
You need a reusable data table with sorting, selection, and custom cells. How would you structure it?
algorithms - 53
A page component fetches data, manages filters, opens dialogs, and renders every section. How would you split it?
components - 54
How would you design an input component that works both inside a form library and as a standalone controlled field?
componentsformsdesign - 55
Rows in an editable React list show values from the wrong item after reordering. How would you debug and fix it?
react - 56
A component copies props into state and sometimes displays stale values. How would you refactor it?
refactoringcomponents - 57
How would you implement a reusable debounced search hook without returning stale results?
hooksdebounce - 58
Several components need to react when an element enters the viewport. How would you build the custom hook?
reactcomponentshooks - 59
Typing in one field causes an entire dashboard to re-render. How would you find the cause?
- 60
When would you wrap a component in React.memo, and how would you verify that it helps?
reactcomponents - 61
A component filters a large collection on every render. How would you decide whether to use useMemo?
components - 62
A memoized child still re-renders because it receives a new callback each time. Would you add useCallback?
callbacksmemoization - 63
A Context provider makes hundreds of consumers re-render whenever one setting changes. How would you fix it?
- 64
A React page freezes while rendering thousands of selectable rows. How would you optimize it?
reactoptimization - 65
Filtering a large result panel makes a controlled input feel laggy. How would you keep typing responsive?
responsiveforms - 66
How would you choose between local state, Context, Zustand, and Redux Toolkit for a new feature?
state - 67
A team copies API responses into Redux and manually tracks loading and freshness. How would you simplify it?
stateapi - 68
A Redux feature stores the same entities nested in several screens and updates become inconsistent. How would you refactor it?
mlopsstaterefactoring - 69
A Zustand component re-renders for every store change even though it displays one field. How would you correct it?
componentsstate - 70
Filters must survive refresh and support shareable links. Where would you store their state?
- 71
How would you implement loading, empty, error, and refresh states for a React Query screen?
reactqueries - 72
Changing a search filter quickly sometimes shows results for an older value. How would you fix the request race?
- 73
How would you add an optimistic toggle to a React Query list without corrupting the cache on failure?
querieslockingcaching - 74
How would you implement an infinite activity feed that avoids duplicate pages and runaway requests?
- 75
An Apollo Client screen issues duplicate GraphQL requests and displays stale related entities. How would you debug it?
graphql - 76
A mutation succeeds, but several React Query screens keep showing old data. How would you design cache updates?
reactqueriesdesign - 77
How would you build a form with hundreds of fields without re-rendering the whole page on every keystroke?
forms - 78
A username field performs server validation, and slow responses overwrite newer input. How would you implement it?
validation - 79
How would you implement an order form where users can add, remove, and reorder line items?
forms - 80
A long settings form needs autosave and protection against overwriting changes from another tab. How would you design it?
formsdesign - 81
Where would you place error boundaries in a large React application?
react - 82
An error thrown in a click handler is not caught by the nearest error boundary. How would you handle it?
react - 83
A route error boundary keeps showing its fallback after the user navigates to a valid record. How would you reset it?
react - 84
How would you write a custom hook for a shared WebSocket connection used by several components?
componentshookswebsockets - 85
How would you implement a useOnlineStatus hook that works with server rendering and multiple consumers?
hooks - 86
How would you test a login form with React Testing Library?
reactformsrtl - 87
A React Testing Library suite breaks after harmless markup refactors. How would you make it resilient?
rtlreactrefactoring - 88
A component fetches data on mount and then refetches after a mutation. How would you test the asynchronous flow?
componentsasync - 89
How would you test a custom hook that depends on React Query and a Context provider?
reacthooksqueries - 90
A test for a debounced autocomplete is flaky in CI. How would you stabilize it?
debounceflaky - 91
How would you make a custom React select accessible without using a native select?
react - 92
A React single-page application changes routes but keyboard focus remains on the old link. How would you fix it?
react - 93
A form marks invalid fields with a red border, but screen-reader users do not learn what failed. How would you repair it?
forms - 94
A clickable card works with a mouse but not with a keyboard. How would you implement it correctly?
- 95
A rarely used chart makes the initial React bundle much larger. How would you load it efficiently?
react - 96
A Next.js page reports hydration mismatches only for some users. How would you debug and fix it?
hydrationnextjs - 97
A Next.js App Router page sends too much JavaScript because its top-level component uses client state. How would you refactor it?
componentsnextjsjavascript - 98
How would you release a risky React checkout change behind a feature flag without leaving two unmaintainable implementations?
reactfeature-flags - 99
Users report a React crash that the team cannot reproduce locally. How would you investigate it in production?
reactdebugging - 100
A React screen becomes slower after repeated navigation and keeps firing duplicate events. How would you find and fix the leak?
react