React Interview Questions for Experienced Developers
React interview questions for developers with 2 to 5 years experience: memoisation, effects done properly, state management choices, routing, testing and TypeScript.
59 questions · 2-5 years experience
At two to five years the questions stop being "what is" and become "when would you". You are expected to have opinions and to be able to defend them with something that happened on a real project.
The most common way to fail this round is not being wrong. It is answering a design question with a definition. If you are asked whether you would use context or Redux and you explain what context is, you have not answered.
What changes at this level
- Trade-offs, not definitions. Every answer should end with the condition that would change your mind.
- Debugging. Expect "this component re-renders on every keystroke, how would you find out why". The answer starts with the Profiler, not with
React.memo. - Your own codebase. How you structure a project, how you test, how you handle data fetching and errors.
- A take-home or a longer coding round. Usually a small feature with an API, marked on state handling, loading and error states, and whether you left the code readable.
The questions, with one line answers
Say each one out loud before you open it. If the sentence does not come out cleanly, follow the link for the full answer and the reasoning behind it.
The function you return from an effect. React runs it before the effect runs again, and once more when the component unmounts, so every subscription, timer or listener is undone exactly once.
React HooksRead the full answer
useEffect runs asynchronously after the browser has painted. useLayoutEffect runs synchronously after the DOM is updated but before paint, so it can measure and adjust layout without the user seeing a flicker.
React HooksRead the full answer
useReducer holds state and updates it by dispatching actions to a reducer function. Prefer it when several state values change together, when the next state depends on the previous one in non-trivial ways, or when the update logic is worth testing on its own.
React HooksRead the full answer
4.What is useMemo, and when is it worth using?
Mid-leveluseMemo caches the result of a calculation between renders and recomputes it only when its dependencies change. It is worth using for genuinely expensive computations, and for keeping an object or array reference stable so a memoised child or an effect does not fire needlessly.
React HooksRead the full answer
useMemo caches the value a function returns; useCallback caches the function itself. useCallback(fn, deps) is exactly useMemo(() => fn, deps).
React HooksRead the full answer
useRef returns a mutable object with a .current property that survives re-renders and never triggers one. It is used to reach a DOM node, and to store a mutable value that the UI does not display, such as a timer id or the previous value of a prop.
React HooksRead the full answer
A custom hook is a function whose name starts with use and which calls other hooks. Write one when the same stateful logic appears in more than one component, or when a component's logic is complex enough that naming it makes the component readable.
React HooksRead the full answer
8.What is useId for?
Mid-leveluseId generates a unique, stable id that matches between the server render and the client hydration. It exists for accessibility attributes such as linking a label to an input, not for keys or database ids.
React HooksRead the full answer
Measure first with the Profiler and a Lighthouse run, then fix what you found: cut the bundle with code splitting, cut unnecessary renders with memoisation and better state placement, and cut the work per render with virtualisation.
PerformanceRead the full answer
10.What is React.memo and when does it not help?
Mid-levelReact.memo wraps a component so React skips re-rendering it when its props are shallowly equal to last time. It does nothing when the props include a new object, array or function each render, or when the component re-renders because of its own state or context.
PerformanceRead the full answer
State that lives too high in the tree, new object or function references passed as props, context values that change identity, and missing memoisation on expensive children. You find them with the React DevTools Profiler and the "highlight updates" option.
PerformanceRead the full answer
Code splitting breaks the bundle into chunks loaded on demand instead of one file up front. React.lazy takes a dynamic import and returns a component; Suspense renders a fallback while that chunk downloads.
PerformanceRead the full answer
Virtualisation renders only the rows currently visible plus a small buffer, and reuses them as the user scrolls. You need it once a list is large enough that the number of DOM nodes, not React, is the bottleneck — typically from a few hundred rows.
PerformanceRead the full answer
14.How do you use the React Profiler?
Mid-levelRecord an interaction in the React DevTools Profiler tab and read the commits: the flamegraph shows what rendered and how long it took, and each component shows why it re-rendered. There is also a Profiler component for measuring in code.
PerformanceRead the full answer
Because it creates a new function identity on every render, which breaks the shallow prop comparison in React.memo and re-triggers any effect that depends on it. On a plain DOM element it costs nothing worth worrying about.
PerformanceRead the full answer
Local useState, lifted state, context, a client store such as Redux Toolkit or Zustand, and a server state library such as TanStack Query. Choose by asking who needs the value, how often it changes, and whether it came from a server.
State ManagementRead the full answer
17.Is the Context API a state management solution?
Mid-levelNot on its own. Context is a way to transport a value down the tree without prop drilling. It has no opinion on how state is stored or updated, and no re-render optimisation, so it is dependency injection rather than state management.
State ManagementRead the full answer
18.What is Redux and what are its core principles?
Mid-levelRedux is a predictable state container. Its three principles are a single source of truth, state that is read only and changed only by dispatching actions, and changes described by pure reducer functions.
State ManagementRead the full answer
Redux Toolkit is the official, batteries-included Redux package. createSlice generates actions and reducers together, Immer lets you write mutating syntax that produces immutable updates, and the store comes preconfigured with thunks and devtools.
State ManagementRead the full answer
Context passes a value down the tree and re-renders every consumer when it changes. Redux is a full state container with selector based subscriptions, middleware and devtools, so components re-render only when the slice they select actually changes.
State ManagementRead the full answer
TanStack Query, formerly React Query, is an async state manager for server data. It caches responses by key, deduplicates in-flight requests, revalidates in the background, and gives you loading, error and stale states without writing them yourself.
State ManagementRead the full answer
22.How do you replicate componentDidMount, componentDidUpdate and componentWillUnmount with hooks?
Mid-levelOne useEffect covers all three: an empty dependency array is mount, a populated array is update, and the returned cleanup function is unmount. The mapping is not exact, because effects synchronise rather than fire on lifecycle events.
Lifecycle & EffectsRead the full answer
Track the first render with a ref and return early. There is no built-in option, and needing this often means the logic belongs in an event handler instead.
Lifecycle & EffectsRead the full answer
Because React 18's StrictMode mounts, unmounts and remounts every component in development to check that your effects clean up after themselves. It does not happen in production.
Lifecycle & EffectsRead the full answer
By default yes: React re-renders the whole subtree. Re-rendering means calling the component function and diffing, not touching the DOM, so it is usually cheap. React.memo skips a child whose props are unchanged.
Lifecycle & EffectsRead the full answer
In practice, with a data library such as TanStack Query, RTK Query or the framework's loader. If you must do it by hand, use an effect keyed on the request inputs, handle loading and error states, and cancel the request in the cleanup.
Lifecycle & EffectsRead the full answer
shouldComponentUpdate lets a class return false to skip a re-render. PureComponent implements it for you with a shallow comparison of props and state. React.memo is the function component equivalent.
Lifecycle & EffectsRead the full answer
Composition means building a component by passing other components into it, usually through children or named props, instead of extending a base component. React recommends it because a component's output is data, so passing that data around is more flexible than inheriting behaviour.
Components & PropsRead the full answer
29.What is prop drilling and how do you avoid it?
Mid-levelProp drilling is passing a prop through components that do not use it, just to reach a descendant that does. You avoid it with component composition, with context, or with a state library, in that order.
Components & PropsRead the full answer
30.What is a higher order component?
Mid-levelA higher order component is a function that takes a component and returns a new component wrapping it with extra behaviour. It was the pre-hooks way of sharing non visual logic between components.
Components & PropsRead the full answer
31.What is the render props pattern?
Mid-levelA render prop is a prop whose value is a function returning JSX. The component owns some behaviour or state and hands it to the caller, who decides what to draw with it.
Components & PropsRead the full answer
32.What are refs, and what does forwardRef do?
Mid-levelA ref is an escape hatch to a DOM node or a mutable value that survives renders without causing one. forwardRef lets a parent attach a ref to a DOM node inside a child component, because refs are not passed through as ordinary props.
Components & PropsRead the full answer
It splits components into containers that fetch data and hold state, and presentational components that only take props and render. Hooks made the strict split much less necessary, but the underlying idea of keeping rendering separate from data access is still good practice.
Components & PropsRead the full answer
An error boundary is a component that catches errors thrown while rendering its subtree and shows a fallback instead of unmounting the whole app. It does not catch errors in event handlers, in asynchronous code, during server rendering, or thrown by the boundary itself.
Advanced ReactRead the full answer
35.What are portals and when do you need one?
Mid-levelcreatePortal renders children into a DOM node outside the parent's hierarchy while keeping them in the React tree. You need it when an ancestor's overflow, z-index or transform would clip or trap a modal, tooltip or dropdown.
Advanced ReactRead the full answer
36.What is Suspense and how does it work?
Mid-levelSuspense lets a component tell React it is not ready, and React shows the nearest boundary's fallback until it is. It powers lazy loaded components, and with a data source that integrates with it, data fetching too.
Advanced ReactRead the full answer
CSR renders in the browser from an empty shell. SSR renders HTML per request. SSG renders HTML at build time. ISR is SSG that regenerates pages in the background after a set interval.
Advanced ReactRead the full answer
Catch them where they happen. Wrap event handlers and async work in try/catch and move the failure into state, use the query library's error state for data fetching, and add window listeners for error and unhandledrejection as a last resort.
Advanced ReactRead the full answer
39.What are synthetic events in React?
Mid-levelA SyntheticEvent is React's cross-browser wrapper around the native event. It has the same interface — preventDefault, stopPropagation, target — but behaves identically across browsers.
Forms & EventsRead the full answer
40.How would you validate a form in React?
Mid-levelValidate on submit and on blur rather than on every keystroke, keep errors in state keyed by field, and put the rules in a schema so the same rules can run on the server. In practice, use React Hook Form with Zod rather than writing it by hand.
Forms & EventsRead the full answer
React's onChange fires on every keystroke, like the native input event. The native change event only fires when the field loses focus. React deliberately normalised this so onChange means "the value changed".
Forms & EventsRead the full answer
Missing label associations, using a div with onClick instead of a button, error messages that are not linked to their field or announced, and losing focus after a dynamic change.
Forms & EventsRead the full answer
Server routing asks the server for a new HTML document on every navigation. Client routing intercepts the click, changes the URL with the History API and swaps components in place, so no document is fetched.
React RouterRead the full answer
44.What are nested routes, and what does Outlet do?
Mid-levelNested routes let a parent route render shared layout and a child route render inside it. Outlet is the placeholder in the parent where React Router renders whichever child matched.
React RouterRead the full answer
45.How do you implement a protected route?
Mid-levelWrap the routes in a component that checks authentication and either renders an Outlet or redirects to the login page, remembering where the user was trying to go.
React RouterRead the full answer
46.How do you code split by route?
Mid-levelWrap each route's component in React.lazy with a dynamic import and put a Suspense boundary above the routes, so each route's code downloads only when the user first visits it.
React RouterRead the full answer
React Testing Library renders components and queries them the way a user would, through visible text and accessible roles. Enzyme exposed the component instance, so tests could reach into state and internal methods, which made them break on every refactor.
TestingRead the full answer
Accessible queries first — getByRole, then getByLabelText, getByPlaceholderText and getByText — then getByTestId as a last resort. The order mirrors how a user, including one with a screen reader, finds things.
TestingRead the full answer
49.How do you test asynchronous behaviour?
Mid-levelUse findBy queries or waitFor, both of which retry until the assertion passes or the timeout expires. Never assert immediately after an action that triggers an async update, and never reach for a fixed setTimeout.
TestingRead the full answer
fireEvent dispatches a single DOM event. userEvent simulates the full interaction a real user produces — for a click that is pointer, mouse down, focus, mouse up and click — so it catches bugs fireEvent walks straight past.
TestingRead the full answer
51.How do you mock network requests in tests?
Mid-levelIntercept at the network layer with Mock Service Worker rather than stubbing fetch or the module that calls it. The component then runs its real data code and the test stays valid when you change HTTP client.
TestingRead the full answer
52.Should you use type or interface for props?
Mid-levelEither works. Interfaces can be merged and extended and give slightly nicer errors for object shapes; type aliases can express unions, intersections and mapped types. Most teams pick one for consistency, and type is the more common default in React code.
React + TypeScriptRead the full answer
53.What is React.FC and why do many teams avoid it?
Mid-levelReact.FC is a type for function components that annotates the whole function rather than its props. Teams moved away from it because it used to add an implicit children prop, it complicates generic components, and annotating the parameter is simpler.
React + TypeScriptRead the full answer
54.How do you type an event handler?
Mid-levelUse React's generic event types parameterised by the element: React.ChangeEvent<HTMLInputElement>, React.MouseEvent<HTMLButtonElement>, React.FormEvent<HTMLFormElement>. Inline handlers usually infer these for you.
React + TypeScriptRead the full answer
55.How do you type useRef?
Mid-levelFor a DOM node use useRef<HTMLInputElement>(null), which gives a read-only current that may be null. For a mutable value use useRef<number | undefined>(undefined), which gives a writable current.
React + TypeScriptRead the full answer
56.Build a search input that debounces its API call
Mid-levelKeep the input controlled for instant feedback, debounce the value with a custom hook, and fire the request from an effect keyed on the debounced value with cancellation in the cleanup.
Coding ChallengesRead the full answer
57.Write a custom useFetch hook
Mid-levelHold data, error and status in one state object, fetch in an effect keyed on the URL, abort in the cleanup, and return the triple. Say out loud that in production you would use a query library.
Coding ChallengesRead the full answer
58.Implement a usePrevious hook
Mid-levelStore the value in a ref and update it in an effect. Because effects run after render, the ref still holds the previous render's value while the component renders.
Coding ChallengesRead the full answer
59.Build a pagination component
Mid-levelTake the current page, total pages and a change handler as props, keep the page in the URL rather than in local state, and render a window of page numbers with ellipses rather than every page.
Coding ChallengesRead the full answer
Where to spend your time
- [Hooks](/react-interview-questions/hooks) in depth.
useMemoversususeCallback, dependency arrays, stale closures. These come up in every interview at this level. - [Performance](/react-interview-questions/performance). Be able to describe a Profiler session in detail.
- [State management](/react-interview-questions/state-management). Practise the client state versus server state distinction until it is automatic.
- [Testing](/react-interview-questions/testing). Even if your current team does not test much, have a position on what is worth testing.
- [TypeScript](/react-interview-questions/typescript). Most roles at this level are TypeScript roles.