React Frontend Interview Questions

The React frontend questions interviewers ask most — from hooks and reconciliation to Next.js SSR, global state, and testing — each with a concise, correct answer. Then practice them in a live mock interview.

Practice these live with an AI interviewer
Get asked questions one at a time and a scored feedback report — free.

11 common React Frontend questions

What is the difference between controlled and uncontrolled components?

A controlled component's value is driven by React state (one source of truth), making it easy to validate and respond to input. An uncontrolled component stores its value in the DOM and you read it via a ref. Controlled is preferred for forms with validation or dynamic behaviour; uncontrolled is simpler for basic read-once forms.

Explain the React reconciliation algorithm.

When state or props change, React re-renders the component tree in memory and diffs it against the previous virtual DOM tree — the reconciliation algorithm. It assumes elements of different types produce different trees (so it replaces them), and uses keys to efficiently reorder list items. Only the minimal set of real DOM mutations is applied.

When would you use useReducer instead of useState?

Use useReducer when state has multiple sub-values that change together, the next state depends on the previous, or the update logic is complex enough to benefit from a centralised reducer function. It makes state transitions explicit and easier to test, similar to a tiny Redux-style pattern without the library.

What is the Context API and what are its performance pitfalls?

Context lets you pass values through the tree without prop drilling. The pitfall: every consumer re-renders whenever the context value changes, even if only an unrelated part changed. Fix by splitting contexts by concern, memoising the value object with useMemo, or reaching for a dedicated state library (Zustand, Jotai) for frequently-changing global state.

How does Next.js SSR differ from SSG and ISR?

SSR (getServerSideProps) generates the page on every request — always fresh but slower. SSG (getStaticProps) generates at build time — fast and cacheable but stale. ISR (revalidate) is SSG that regenerates in the background after a time interval — the best of both for content that changes occasionally. Choose based on how often the data changes and your traffic patterns.

What is code-splitting and how do you implement it in React?

Code-splitting breaks the JavaScript bundle into smaller chunks loaded on demand, so the initial page loads faster. Use React.lazy() with Suspense to lazy-load components, and dynamic import() for libraries. Next.js does route-level splitting automatically. Profile with the browser's Coverage tab to find unused code.

How do you optimise a React app that re-renders too often?

Profile first with React DevTools Profiler to find expensive renders. Then: wrap pure components with React.memo to skip renders when props haven't changed, use useCallback to stabilise function props, use useMemo for expensive computations, split context by concern to narrow update scope, and avoid creating new objects/arrays inline in JSX.

What is Zustand and how does it compare to Redux?

Zustand is a lightweight global state library using a simple hook-based API with no boilerplate — you define a store with state and actions in one place. Redux is more structured with actions, reducers, and middleware, and comes with Redux DevTools for time-travel debugging. Zustand is faster to set up for most apps; Redux shines in large teams that need strict conventions and advanced tooling.

How do you test React components?

Use React Testing Library with Jest (or Vitest). Write tests from the user's perspective — query by accessible role, label, or text (getByRole, getByLabelText) rather than implementation details. For async behaviour use waitFor or findBy queries. Mock network calls with MSW (Mock Service Worker). For E2E flows use Playwright or Cypress.

What are React Server Components?

RSCs render on the server and send HTML (with zero client JS for the component itself) — ideal for data fetching and non-interactive UI. They can import server-only code (direct DB queries, secrets). They can't use state, effects, or browser APIs — those stay in Client Components ('use client'). Compose them: a Server Component can render Client Component children, but not vice versa.

What is hydration and what causes hydration errors?

Hydration is the process of React attaching event listeners to server-rendered HTML, making it interactive. Hydration errors occur when the server-rendered HTML doesn't match what React would render on the client — common causes: using Math.random() or Date.now() without fixing the seed, rendering based on window/localStorage (which doesn't exist server-side), or incorrect nesting (e.g. <p> inside <p>).

Ready to practice out loud?

Reading answers is one thing — saying them under pressure is another. Run a free AI mock interview and get scored feedback.

Start a mock interview

More interview questions