Skip to content

Senior React Developer Interview Questions & Answers

40 questions for Senior React Developer interviews — 13 medium, 27 hard.

About the Senior React Developer role

A senior React developer owns the frontend of a product area: designing component architecture and state flow, reviewing code, setting testing standards and solving performance problems. They mentor juniors, work with product and backend teams on API contracts and estimates, and make technology choices such as when to adopt Next.js, the React Compiler or a new state library. Typical experience is four to seven years.

Component architecture Performance profiling Testing strategy Code review and mentoring TypeScript at scale
Solved for this roleStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What are the common styling options in React, and how do Server Components affect the choice?

Save to ▾
Show answer
Options include plain CSS or CSS Modules (scoped class names), Tailwind CSS utility classes, Sass, and CSS-in-JS libraries like styled-components or Emotion. Runtime CSS-in-JS needs client-side JavaScript and context, so it fits poorly with Server Components. That is why Tailwind and CSS Modules, or zero-runtime libraries, are the most common choice in modern Next.js projects. Component libraries like shadcn/ui build on Tailwind.
02

What does the 'use client' directive do?

Save to ▾
Show answer
'use client' at the top of a file marks a boundary: that module and everything it imports become part of the client bundle and can use state, effects, event handlers and browser APIs. It does not mean the component is only rendered on the client; it is still pre-rendered to HTML on the server and then hydrated. Keep 'use client' as low in the tree as possible to send less JavaScript.
03

How do you fetch data in a Next.js App Router page?

Save to ▾
Show answer
Make the page an async Server Component and await data directly. // app/products/[id]/page.tsx export default async function ProductPage({ params }) { const { id } = await params; const product = await getProduct(id); if (!product) notFound(); return ( <main> <h1>{product.name}</h1> <AddToCartButton id={id} /> </main> ); } AddToCartButton is a Client Component. In recent Next.js versions params is a promise.
04

A blog feature must render HTML content that comes from a CMS. Why is dangerouslySetInnerHTML risky and how do you use it safely?

Save to ▾
Show answer
React escapes values in JSX by default, which protects against XSS. dangerouslySetInnerHTML bypasses this and inserts raw HTML, so if the content comes from users or an untrusted CMS, attackers can inject scripts. If you must render HTML, sanitise it first with a library like DOMPurify, restrict allowed tags, and add a Content Security Policy. Also never put user input into href attributes without validating the protocol.
05

What is middleware, now called proxy, in Next.js?

Save to ▾
Show answer
It is code that runs before a request completes, at the edge of the app, and can rewrite, redirect, set headers or cookies based on the request. In Next.js 16 the middleware.ts file convention was renamed to proxy.ts, with the same idea. Typical uses are redirecting unauthenticated users, locale detection, A/B testing and bot filtering. Keep it light, and still check authorisation in data access code.
06

Typing in a search box feels laggy because a big product list is filtered on every keystroke. How do you fix it?

Save to ▾
Show answer
Keep the input state urgent and make the expensive part deferred. Use const deferredQuery = useDeferredValue(query) and filter with deferredQuery inside useMemo, and wrap the list in React.memo. The input updates instantly while React renders the list in the background and can interrupt it. If filtering is still heavy, debounce it, move it to a Web Worker or filter on the server.
07

How do you track errors that happen in production React apps?

Save to ▾
Show answer
Use an error monitoring tool such as Sentry, which captures exceptions with stack traces, browser and user context. Upload source maps during the build so minified stack traces map back to your source, but do not serve them publicly. Wrap major sections in error boundaries that report errors and show friendly fallbacks. Add release tags so you can see which deployment introduced a bug.
08

Why normalise state in Redux and what does createEntityAdapter do?

Save to ▾
Show answer
Normalising means storing items in a lookup like { ids: [...], entities: { id: item } } instead of nested arrays. Each item exists once, updates are O(1) and you avoid duplicated data getting out of sync. createEntityAdapter in Redux Toolkit generates this structure plus reducers like addOne, upsertMany and removeOne, and memoised selectors such as selectAll and selectById.
09

You inherit an old Redux codebase with connect, hand-written action types and switch reducers. How would you modernise it?

Save to ▾
Show answer
I would migrate gradually, not in one big rewrite. First replace createStore with configureStore, which keeps old reducers working. Then convert one feature at a time to createSlice, switch components from connect to useSelector and useDispatch, and move data fetching to RTK Query. Add tests around each feature before migrating, and remove dead actions. Each step ships independently and reduces risk.
10

A test in CI fails randomly about one time in ten. How do you handle a flaky test?

Save to ▾
Show answer
First reproduce it by running the test repeatedly and in random order. Common causes are shared state between tests, missing awaits, real timers or dates, network calls not mocked and tests depending on execution order. Fix the root cause: reset mocks and stores in afterEach, use findBy or waitFor instead of fixed sleeps, freeze time with fake timers. Quarantine it with a ticket only temporarily, never ignore it.
11

How did you bring better testing practices to a team that had very few tests?

Save to ▾
Show answer
Situation: our React app had almost no tests and regressions reached production every release. Task: improve quality without slowing delivery. Action: I set up Vitest, React Testing Library and MSW, wrote example tests for two key screens, ran a short session for the team and added a rule that bug fixes include a test. Result: within three months, critical flows were covered and regressions dropped noticeably.
12

What are React Server Components?

Save to ▾
Show answer
Server Components run only on the server or at build time. They can be async, read databases or files directly and send rendered output to the client without shipping their JavaScript, which reduces bundle size. They cannot use state, effects or browser APIs. Client Components, marked with 'use client', handle interactivity. Server Components can render Client Components and pass them serialisable props.
13

How do you test a component that depends on Redux and React Router?

Save to ▾
Show answer
Create a custom render helper that wraps the UI with real providers. function renderWithProviders(ui, { route = '/', preloadedState } = {}) { const store = configureStore({ reducer: rootReducer, preloadedState }); return render( <Provider store={store}> <MemoryRouter initialEntries={[route]}>{ui}</MemoryRouter> </Provider> ); } Using a real store with preloaded state is better than mocking useSelector, because it tests actual behaviour.
14

Field data shows poor INP on the 'Add to cart' button of a product page. How do you improve it?

Save to ▾
Show answer
Profile the click to see what runs. Typical problems are a large synchronous re-render of the whole page, heavy analytics code and expensive state updates in the handler. Update the button feedback first and wrap the non-urgent part (cart drawer, recommendations) in startTransition, defer analytics with setTimeout or requestIdleCallback, narrow which components subscribe to cart state and break up long tasks.
15

What resource preloading APIs did React 19 add?

Save to ▾
Show answer
React 19 added functions in react-dom such as preload, preinit, prefetchDNS and preconnect. They tell the browser to load fonts, stylesheets, scripts or connect to API origins early, and React places the hints in the document head, including during server rendering. React 19 also supports rendering <title>, <meta> and <link> tags inside components, hoisting them to the head automatically.
16

In a Next.js app you see a hydration mismatch error. How do you debug it?

Save to ▾
Show answer
It means the HTML rendered on the server differs from the first client render. Common causes: using Date.now(), Math.random() or locale formatting in render, reading window or localStorage during render, browser extensions changing the DOM, and invalid HTML nesting like a div inside a p. Read the diff in the error, render client-only values inside useEffect, use useId for ids and fix invalid markup.
17

Your tests pass but print 'An update to Component inside a test was not wrapped in act(...)'. What does it mean and how do you fix it?

Save to ▾
Show answer
It means state changed after the test finished checking, usually because an async operation like a fetch or timer resolved later. The test may not be checking the final UI. Fix it by awaiting the result: use findBy queries or waitFor for the expected content, await user-event calls, and use fake timers with act when testing timeouts. Do not just wrap random code in act to hide the warning.
18

Without using memo, what structural techniques reduce unnecessary re-renders?

Save to ▾
Show answer
Move state down into the smallest component that needs it, so changes do not re-render siblings. Lift content up by passing expensive parts as children: a component that changes state does not re-render JSX it receives as children, because that JSX was created by the parent. Split large components, and avoid putting fast-changing values in widely used context. These often fix performance more cleanly than memoisation.
19

What are memoised selectors and why use createSelector?

Save to ▾
Show answer
A selector reads or derives data from the store. If a selector returns a new array each time, such as state.todos.filter(t => t.done), useSelector sees a new reference and re-renders on every store update. createSelector from Reselect, included in Redux Toolkit, caches the result and recomputes only when its input selectors return changed values, avoiding wasted renders and repeated expensive calculations.
20

After a release, the Lighthouse performance score of the home page dropped from 90 to 60. How do you find and fix the cause?

Save to ▾
Show answer
Compare the two builds instead of guessing. Run Lighthouse and WebPageTest on both versions, check which metric dropped (LCP, TBT or CLS), and diff bundle analyser reports to spot new heavy dependencies. Review the release changes: a new third-party script, an unoptimised hero image or a component moved from server to client are common causes. Fix it, then add a performance budget check in CI to prevent repeats.
21

Describe how you led a large frontend migration.

Save to ▾
Show answer
Situation: our app ran on an unmaintained Create React App setup with slow builds. Task: move to Vite without stopping feature work. Action: I wrote a migration plan, fixed incompatible imports and env variables in a branch, ran both builds in CI for a week, and trained the team on differences. Result: we switched over a weekend, local start time went from over a minute to a few seconds, and nothing broke for users.
22

How do you add multiple languages to a React app?

Save to ▾
Show answer
Use an i18n library such as react-i18next or, in Next.js, next-intl. Store translations in JSON files per locale, reference keys like t('cart.title') instead of hard-coded text, and handle plurals, dates, numbers and currency with Intl APIs. Put the locale in the URL, like /hi/products, for SEO and shareable links. For Indian audiences, check fonts for Devanagari and other scripts and test longer translated text.
23

How does caching work in modern Next.js?

Save to ▾
Show answer
Next.js can cache rendered routes and data. In Next.js 15 and later, fetch requests and GET route handlers are not cached by default; you opt in with options like next: { revalidate: 3600 } or the 'use cache' directive with Cache Components in newer versions. You invalidate with revalidatePath or revalidateTag after mutations. The router also caches visited pages on the client. Understanding what is static versus dynamic avoids stale data bugs.
24

How would you build and maintain a shared component library for several React apps?

Save to ▾
Show answer
Start with design tokens for colours, spacing and typography, and build accessible primitives, often on top of headless libraries like Radix UI or React Aria. Document components in Storybook with usage examples, add visual regression and accessibility tests, and publish versioned packages from a monorepo with semantic versioning and changelogs. Keep APIs small and composable, and collect feedback from consuming teams before breaking changes.
25

What are micro-frontends and when are they worth it?

Save to ▾
Show answer
Micro-frontends split a large web app into independently built and deployed parts owned by different teams, for example search, cart and account, combined at runtime using Module Federation, iframes or route-level composition. They help very large organisations scale teams and deployments. The costs are duplicated dependencies, harder shared state, inconsistent UX and complex tooling, so they are rarely worth it for small or medium teams.
26

After adding an AuthContext at the root, profiling shows the whole app re-rendering every few seconds. What would you check?

Save to ▾
Show answer
Check what the provider value is and what updates it. Likely the value is a new object each render, or it includes fast-changing data such as a token refresh timer or a clock. Memoise the value with useMemo, move frequently changing data out of the context, and split it into separate contexts, so components reading only the user do not re-render when unrelated fields change.
27

Explain the testing pyramid and the testing trophy. Which applies to frontend?

Save to ▾
Show answer
The pyramid says write many unit tests, fewer integration tests and very few end-to-end tests, because lower tests are fast and cheap. The testing trophy, popular for frontend, adds static analysis at the base and puts the most effort in integration tests, since they give the best confidence per cost. For React, I rely on TypeScript and ESLint, many component tests, some unit tests for logic and a few E2E tests.
28

Tell me about a time you improved the performance of an application.

Save to ▾
Show answer
Situation: our admin dashboard took about eight seconds to become usable on office laptops. Task: bring it under three seconds. Action: I profiled it, found a 2 MB bundle and a chart library loaded on every page, lazy loaded routes and charts, replaced moment with dayjs and virtualised a large table. Result: load time dropped to around 2.5 seconds and support complaints about slowness stopped.
29

How would you implement an optimistic update with TanStack Query and roll back on failure?

Save to ▾
Show answer
In useMutation, use onMutate to cancel ongoing queries, save the previous cache data and update the cache with the expected result. In onError, restore the saved snapshot and show an error toast. In onSettled, invalidate the query so the cache syncs with the server. This makes actions like toggling a favourite feel instant while keeping data correct if the server rejects the change.
30

A new mid-sized dashboard project is starting. How would you decide between Context, Redux Toolkit and Zustand?

Save to ▾
Show answer
First separate server state, which I would handle with TanStack Query or RTK Query. For remaining client state, local useState covers most needs. Context suits rarely changing values like theme or auth. If there is complex shared state with many actions, strict patterns, large teams and need for DevTools time travel, Redux Toolkit fits. For simpler shared state with less boilerplate, Zustand is a good choice.
31

What is the React Compiler?

Save to ▾
Show answer
The React Compiler, released as stable version 1.0 in late 2025, is a build-time tool (Babel plugin, also integrated in Vite and Next.js setups) that automatically memoises components and values. It analyses your code and inserts caching similar to useMemo, useCallback and React.memo, so developers write plain code. It requires following the rules of React, such as pure rendering, and can be adopted gradually per directory.
32

A teammate wraps every function in useCallback and every value in useMemo for performance. When should you not memoise, and what feedback would you give?

Save to ▾
Show answer
Memoisation has costs: extra memory, comparisons on every render and more complex code. Skip it for cheap calculations, components that rarely re-render, and props that change every render anyway. Memoising everything by default also hides design problems like state placed too high. Use the profiler to find real bottlenecks first. With the React Compiler, manual memoisation is mostly needed only as an escape hatch.
33

After navigating between pages for a while, the app's memory keeps growing and it slows down. How do you investigate a memory leak?

Save to ▾
Show answer
Take heap snapshots in Chrome DevTools Memory panel before and after repeated navigation and compare retained objects, especially detached DOM nodes. Common React causes are effects without cleanup: intervals, event listeners on window, WebSocket subscriptions and third-party chart instances not destroyed. Also check global caches growing without limits. Add cleanups in useEffect returns and verify the heap stabilises.
34

What is Redux middleware?

Save to ▾
Show answer
Middleware sits between dispatching an action and the reducer, letting you intercept actions for side effects. Signature: store => next => action => {...}. Common uses are async logic (redux-thunk, included by default in Redux Toolkit), logging, analytics, error reporting and the RTK Query cache middleware. Redux Toolkit also provides listenerMiddleware for reacting to actions, a lighter alternative to redux-saga for most cases.
35

An e-commerce site has one lakh product pages whose prices change a few times a day. Which rendering strategy would you choose in Next.js?

Save to ▾
Show answer
Building all pages statically at deploy time would be slow, and full SSR on every request adds server load. I would pre-render the most popular products at build time, generate the rest on first request and cache them, and revalidate on demand with revalidateTag when prices change in the admin. Stock and price shown in the cart would be fetched fresh. This gives static speed with correct data.
36

When would you add end-to-end tests with Playwright or Cypress?

Save to ▾
Show answer
Add E2E tests for critical business flows that cross many components and the backend, such as signup, login, search, add to cart and payment. They run in real browsers and catch integration issues unit tests miss. They are slower and more brittle, so keep them few and focused, use stable selectors like roles or data-testid, seed test data and run them in CI on every pull request.
37

You wrapped a row component in React.memo, but the profiler shows it still re-renders every time. The parent passes onClick={() => remove(id)}. Why?

Save to ▾
Show answer
An inline function like onClick={() => remove(id)} creates a new function object on every render. React.memo compares props by reference, sees a different function and re-renders the child every time, so memo has no effect. Wrap the handler with useCallback and correct dependencies, or let the React Compiler handle it. If the child is not memoised, inline functions are fine and cheap.
38

When would you use a Web Worker in a React application?

Save to ▾
Show answer
Use a Web Worker for CPU-heavy work that would block the main thread, such as parsing a large CSV, image processing, complex calculations or searching big datasets in the browser. The worker runs in a separate thread and communicates through postMessage, so the UI stays responsive. Libraries like Comlink simplify the messaging. Workers cannot touch the DOM, so results are sent back and set in state.
39

How do you persist part of your state, like the cart, across page reloads?

Save to ▾
Show answer
Save it to localStorage and read it on startup. With Zustand, the persist middleware does this. import { persist } from 'zustand/middleware'; const useCart = create(persist( set => ({ items: [], add: i => set(s => ({ items: [...s.items, i] })) }), { name: 'cart-storage' } )); With Redux, use redux-persist or a store.subscribe that writes a throttled snapshot. Never store secrets like tokens in localStorage.
40

Tell me about a time you had to learn a new tool or library quickly.

Save to ▾
Show answer
Situation: our project needed to switch from Jest to Vitest with a week's notice. Task: migrate around 300 tests. Action: I read the official migration guide, migrated one folder first to discover patterns, wrote a codemod for jest.fn to vi.fn replacements and documented gotchas for the team. Result: we finished in four days, test runs became much faster, and the guide helped others with later work.

Frequently asked questions

What does a Senior React Developer do?

A senior React developer owns the frontend of a product area: designing component architecture and state flow, reviewing code, setting testing standards and solving performance problems. They mentor juniors, work with product and backend teams on API contracts and estimates, and make technology choices such as when to adopt Next.js, the React Compiler or a new state library. Typical experience is four to seven years.

Which skills are tested in a Senior React Developer interview?

Expect questions on Component architecture, Performance profiling, Testing strategy, Code review and mentoring, TypeScript at scale. Most rounds also ask you to explain a project and solve one practical problem live.

How do I prepare for a Senior React Developer interview?

Revise Performance Optimization, Testing and Debugging, State Management, Next.js and Advanced React first using the topic sheets, practise the questions on this page aloud, then do one full mock interview to practise timing.