Top React.js Interview Questions Interview Questions | CandidateToHR
Ace your React frontend interview with 50+ real questions covering Hooks, Virtual DOM, Component Lifecycle, Redux, Performance Optimization, and Concurrent Mode.
CandidateToHR provides highly optimized, professional tech career resources. Build, customize, and analyze your tech career credentials completely free.
React is the world's most widely used frontend library. Prepare for your next interview with our curated list of 50+ real questions covering beginner fundamentals, advanced hooks, performance optimization, and system-level architecture.
Top Interview Questions & Answers
Beginner Interview Questions
Q: What is React and what problem does it solve?
A: React is an open-source JavaScript library developed by Facebook for building user interfaces, particularly single-page applications (SPAs). It solves the problem of efficiently updating the UI in response to data changes. By using a Virtual DOM, React minimizes direct manipulation of the actual browser DOM (which is slow), computing the minimal set of changes needed and applying them in a single, efficient batch.
Q: What is JSX?
A: JSX (JavaScript XML) is a syntax extension for JavaScript that looks like HTML. It allows developers to write UI structure directly in JavaScript files. JSX is not valid JavaScript — it must be compiled by a tool like Babel into `React.createElement()` calls. For example, `
Hello
` compiles to `React.createElement('h1', null, 'Hello')`.
Q: What is the Virtual DOM and how does it work?
A: The Virtual DOM (VDOM) is a lightweight, in-memory representation of the actual browser DOM. When component state changes, React creates a new VDOM tree and compares it with the previous one using a diffing algorithm called Reconciliation. React then calculates the minimum number of real DOM updates required and applies them in a batch, which is significantly faster than re-rendering the entire DOM.
Q: What is the difference between a class component and a functional component?
A: Class components use ES6 classes and can manage state via `this.state` and lifecycle methods (`componentDidMount`, etc.). Functional components are plain JavaScript functions. Before React 16.8, functional components were stateless. After hooks were introduced, functional components can now manage state (`useState`), side effects (`useEffect`), and more, making class components mostly legacy.
Q: What are props?
A: Props (short for 'properties') are read-only inputs passed from a parent component to a child component. They are immutable from the child's perspective. Props allow components to be dynamic and reusable. A child cannot modify its own props — any change must originate from the parent passing a different value.
Q: What is state in React?
A: State is an internal, mutable data store within a component. When state changes, React automatically re-renders the component and its children. In functional components, state is managed via the `useState` hook. Unlike props (passed from outside), state is owned and managed by the component itself.
Q: What is `useState`?
A: `useState` is a React Hook that lets you add state to a functional component. It returns an array with two items: the current state value and a setter function. Example: `const [count, setCount] = useState(0)`. Calling `setCount(1)` triggers a re-render with the new value. The initial state is only used on the first render.
Q: What is `useEffect`?
A: `useEffect` is a React Hook for handling side effects (API calls, subscriptions, DOM manipulation). It runs after the component renders. You control when it re-runs via its dependency array: an empty `[]` means run once on mount, `[value]` means run when `value` changes, and omitting the array means run after every render. Return a cleanup function to run on unmount.
Q: What is the key prop and why is it important?
A: The `key` prop is a special string attribute you must provide when creating lists of elements. React uses keys to identify which items have changed, been added, or removed, enabling efficient list reconciliation. Keys must be stable, unique, and predictable — ideally a unique ID from your data. Using array index as a key is an anti-pattern when the list can be reordered.
Q: What is conditional rendering in React?
A: Conditional rendering means displaying different components or elements based on state or props. Common patterns include the ternary operator (`condition ? : `), the logical AND short-circuit (`condition && `), or returning early from the render function. Avoid `if/else` inside JSX directly as it is not valid.
Q: What is the difference between controlled and uncontrolled components?
A: In a **controlled component**, form input values are driven by React state. The `value` attribute is bound to state, and an `onChange` handler updates it. In an **uncontrolled component**, form data is handled by the DOM itself via `ref.current.value`. Controlled components are the React-recommended approach as they make state the single source of truth.
Q: What are React Fragments?
A: Fragments let you group a list of children without adding extra DOM nodes. A component can only return one root element, and wrapping everything in a `
` adds unnecessary DOM nodes that can break CSS. Using `` (or the shorthand `<>...>`) solves this without polluting the DOM.
Q: What is the difference between `props.children` and passing props explicitly?
A: `props.children` is a special prop automatically populated with whatever is nested between a component's opening and closing JSX tags. This is used for wrapper/layout components (like a `Card` or `Modal`) that don't know their content in advance. Explicit props are named and passed as attributes: ``.
Q: What is an event handler in React?
A: React uses synthetic events — wrappers around native browser events that normalize cross-browser behavior. Event handlers are camelCase (e.g., `onClick`, `onChange`). You pass a function reference, not a call: `
Q: What is prop drilling and why is it a problem?
A: Prop drilling is the pattern of passing props through multiple layers of components just to get data to a deeply nested child that needs it. Intermediate components receive and forward props they don't directly use. This creates tight coupling, makes refactoring painful, and hurts code readability. Solutions include Context API or a global state manager like Redux.
Q: What is one-way data flow in React?
A: React enforces one-way (unidirectional) data flow: data passes from parent to child via props, never the other way. A child cannot directly modify a parent's state. Instead, the parent passes a callback function as a prop, which the child calls to request a state change in the parent. This makes data flow predictable and debugging easier.
Q: What is `useRef`?
A: `useRef` returns a mutable ref object whose `.current` property is persisted across renders. It has two primary uses: (1) **Accessing DOM nodes directly** — `const inputRef = useRef(); inputRef.current.focus()`. (2) **Storing mutable values** that don't trigger a re-render when changed, unlike state (e.g., storing a previous value, a timer ID, or a flag).
Intermediate Interview Questions
Q: What is the Context API and when should you use it?
A: The Context API allows you to share data (like a theme, user auth, or locale) across the entire component tree without prop drilling. You create a context with `React.createContext()`, wrap a part of the tree with a `Provider` passing a `value`, and consume it in any nested component using `useContext()`. Use it for truly global, infrequently-updating state; avoid it for high-frequency updates as it re-renders all consumers.
Q: What is `useMemo` and when should you use it?
A: `useMemo` memoizes the result of an expensive computation, recalculating only when its dependencies change. Syntax: `const result = useMemo(() => expensiveCalc(a, b), [a, b])`. Use it when a computation is genuinely expensive and runs on every render. Don't use it prematurely — the memoization itself has overhead. Only optimize when you have measured a performance problem.
Q: What is `useCallback` and how is it different from `useMemo`?
A: `useCallback` memoizes a function reference, preventing it from being recreated on every render. `const handleClick = useCallback(() => doSomething(id), [id])`. The critical difference: `useMemo` returns a **value**, while `useCallback` returns a **function**. Use `useCallback` when passing stable callback references to child components wrapped in `React.memo` to prevent unnecessary child re-renders.
Q: What is `React.memo`?
A: `React.memo` is a Higher-Order Component (HOC) that memoizes a functional component, preventing re-renders if its props haven't changed (shallow comparison). `const MemoizedChild = React.memo(ChildComponent)`. It's the functional equivalent of `shouldComponentUpdate`. It pairs with `useCallback` — if you pass a new function reference on every render, `React.memo` is bypassed.
Q: What are custom hooks?
A: A custom hook is a reusable JavaScript function whose name starts with `use` and that calls other hooks internally. They allow you to extract stateful logic out of components and share it. For example, `useFetch(url)` can encapsulate data fetching, loading state, and error handling. They do not create a new component instance — the state is local to the component that calls them.
Q: What is `useReducer` and when do you use it over `useState`?
A: `useReducer` is an alternative to `useState` for managing complex state logic. It uses a reducer pattern: `const [state, dispatch] = useReducer(reducer, initialState)`. You dispatch actions (`dispatch({ type: 'INCREMENT' })`) and the reducer function handles state transitions. Use it when: state has multiple sub-values, the next state depends on the previous, or update logic is complex enough to deserve its own function.
Q: What is code splitting and lazy loading in React?
A: Code splitting is the process of splitting your bundle into smaller chunks loaded on demand. React provides `React.lazy()` and `Suspense` for this. `const LazyPage = React.lazy(() => import('./PageComponent'))`. Wrap it in `}>` to handle the loading state. This dramatically improves initial page load time by not shipping code the user hasn't navigated to yet.
Q: What is the difference between `useEffect` and `useLayoutEffect`?
A: Both run after render, but timing differs. `useEffect` runs **asynchronously** after the browser has painted the screen. `useLayoutEffect` runs **synchronously** after all DOM mutations but before the browser paints. Use `useLayoutEffect` when your effect reads or writes to the DOM and you need to prevent a visual flicker (e.g., measuring an element's size). For most cases, `useEffect` is preferred.
Q: What is React Router and what is client-side routing?
A: React Router is the standard library for handling navigation in React SPAs. In client-side routing, navigation is handled by JavaScript in the browser — the server only serves one HTML file (the SPA shell). When a user navigates, React Router intercepts the URL change and renders the appropriate component, without a full page reload. ``, ``, `useNavigate()`, and `useParams()` are core concepts.
Q: What are Higher-Order Components (HOCs)?
A: A HOC is a function that takes a component as input and returns a new enhanced component with additional behavior. Pattern: `const EnhancedComponent = withSomething(WrappedComponent)`. HOCs were the primary way to reuse component logic before hooks. Examples include `withAuth` (for route protection) or `withTheme`. Today, custom hooks are generally preferred as they are more composable.
Q: What are Render Props?
A: Render Props is a pattern where a component accepts a function as a prop and calls it to determine what to render. `} />`. Like HOCs, it was a pre-hooks technique for sharing stateful logic. While still valid, custom hooks have largely superseded render props for logic sharing.
Q: How does reconciliation work in React?
A: Reconciliation is the process React uses to diff the new Virtual DOM tree against the previous one to determine minimal DOM updates. React uses two heuristics: (1) Elements of different types produce entirely different trees (it destroys and recreates). (2) The developer can hint at stable children using the `key` prop. The algorithm is O(n) rather than O(n³) because of these optimizations.
Q: What is lifting state up?
A: Lifting state up is the pattern of moving shared state from child components to their closest common ancestor. When two sibling components need to share and synchronize data, the state is moved to the parent, which then passes the data down as props and passes setter callbacks for children to trigger updates. This keeps state as the single source of truth.
Q: What is the difference between `useEffect` cleanup and `componentWillUnmount`?
A: In class components, `componentWillUnmount` runs once when the component is destroyed. In `useEffect`, returning a function from the effect provides cleanup. Crucially, this cleanup also runs **before the effect runs again** when dependencies change (not just on unmount). This prevents stale event listeners, subscriptions, or timers from the previous effect run.
Q: What is the Strict Mode in React?
A: `` is a development tool that highlights potential problems. It intentionally double-invokes functions (like state updaters and render methods) to detect side effects, warns about deprecated lifecycle methods, and in React 18+, simulates component unmounting/remounting to test for cleanup correctness. It has no effect on production builds.
Q: What is the difference between state batching in React 17 vs. React 18?
A: In React 17, state batching (grouping multiple `setState` calls into a single re-render) only happened inside React event handlers. Calls inside `setTimeout`, Promises, or native event listeners would trigger separate renders for each `setState`. In React 18, **Automatic Batching** extends this to all state updates everywhere, reducing unnecessary re-renders.
Q: How do you make API calls in React?
A: The standard approach is inside a `useEffect` hook. Call the async function and set data to state on success. Always handle loading and error states. Cancel ongoing requests when the component unmounts using an AbortController (or a cleanup return from `useEffect`) to prevent state updates on unmounted components ('Can't perform a React state update on an unmounted component' warning).
Advanced Interview Questions
Q: What is the React Fiber Architecture?
A: React Fiber (introduced in React 16) is the complete rewrite of React's core reconciliation algorithm. The previous 'Stack Reconciler' was synchronous — once started, it couldn't pause mid-tree. Fiber makes rendering work interruptible: React can pause reconciliation to handle higher-priority work (like user input), then resume where it left off. This is the foundation for Concurrent Mode features.
Q: What is Concurrent Mode / Concurrent Features in React 18?
A: Concurrent Mode (now 'Concurrent Features' in React 18) allows React to prepare multiple versions of the UI simultaneously. It unlocks features like: `startTransition` (marking non-urgent state updates so React can defer them), `useDeferredValue`, `` for data fetching, and `useId`. The key benefit is that React can interrupt long renders to keep the UI responsive to user input.
Q: What is `startTransition` and when do you use it?
A: `startTransition` marks a state update as non-urgent, allowing React to defer it while prioritizing more critical updates (like keystrokes). Wrapping a slow state update — like filtering a large list — inside `startTransition(() => setSearch(value))` ensures the input field stays responsive while the expensive filtering happens in the background. `useTransition` provides a `isPending` flag to show a loading indicator.
Q: [Scenario] Your React app is rendering slowly. Walk me through how you'd diagnose and fix it.
A: 1) **Profile first:** Use React DevTools Profiler to identify which components are re-rendering unnecessarily and how long they take. 2) **Prevent unnecessary re-renders:** Wrap pure child components with `React.memo`. Stabilize callback and object props with `useCallback` and `useMemo`. 3) **Virtualize large lists:** Use `react-window` or `react-virtual` to only render visible rows. 4) **Code split routes:** Use `React.lazy` for routes. 5) **Defer non-critical updates:** Use `startTransition` for slow state transitions.
Q: What is Server-Side Rendering (SSR) in the context of React?
A: SSR renders the React component tree on the server into an HTML string, which is sent to the browser. The browser displays it immediately (fast First Contentful Paint), then React 'hydrates' the HTML — attaching event listeners. SSR improves SEO (bots see real content) and perceived performance. Next.js is the de facto React framework for SSR. The tradeoff is server load and complexity.
Q: What is React's `forwardRef`?
A: `forwardRef` allows a parent component to get direct access to a DOM node inside a child component. Since `ref` is not a regular prop, it doesn't get passed down automatically. `React.forwardRef((props, ref) => )` explicitly passes the ref through. This is commonly used in reusable UI libraries for components like modals, inputs, or date pickers.
Q: What is the `useImperativeHandle` hook?
A: `useImperativeHandle` is used with `forwardRef` to customize the instance value that is exposed to the parent when it uses a ref. Instead of exposing the raw DOM node, you can expose a curated set of methods: `useImperativeHandle(ref, () => ({ focus: () => inputRef.current.focus() }))`. This creates a clean, controlled API surface rather than giving parents unrestricted DOM access.
Q: What is the Compound Component Pattern?
A: The Compound Component Pattern groups related components that share implicit state via Context. Think of HTML `
Q: How do you prevent memory leaks in React?
A: Memory leaks occur when a component unmounts but async operations (API calls, timers, subscriptions) still reference its state. Fix them by: 1) Returning cleanup functions from `useEffect` to cancel subscriptions/timers. 2) Using `AbortController` to cancel fetch requests on unmount. 3) Checking an `isMounted` flag (or using Ref) before calling `setState` inside async callbacks.
Q: What is Error Boundary in React?
A: Error Boundaries are class components that catch JavaScript errors in their child component tree during rendering, log them, and display a fallback UI instead of crashing. They use `componentDidCatch()` and `getDerivedStateFromError()`. Notably, hooks cannot implement Error Boundaries — they must be class components. Libraries like `react-error-boundary` provide a functional wrapper.
Q: What is the difference between Redux and React Context?
A: Context is built into React and is ideal for static or slowly-changing data (themes, user auth). Redux is a dedicated global state management library with a strict unidirectional data flow, DevTools for time-travel debugging, middleware support (for async with Redux Thunk/Saga), and performance optimizations like selector memoization (Reselect). Use Context for simple shared state; use Redux/Zustand for complex state with frequent updates.
Q: [Scenario] Explain how you would test a React component.
A: I use **React Testing Library (RTL)** paired with **Jest**. RTL's philosophy is to test components as users interact with them — find elements by `role`, `text`, or `labelText`, not by CSS class or implementation details. For a form: render it, `userEvent.type` into inputs, `userEvent.click` submit, then `expect` to find the success message. For async effects, use `waitFor`. For unit-testing logic, use Jest directly on the pure functions.
Q: What are React Server Components (RSC)?
A: React Server Components (introduced in React 18/Next.js 13+) are components that run exclusively on the server and are never sent to the client as JavaScript. They can directly access databases, file systems, and secrets without security risks, and they reduce the client bundle size. They cannot use state, effects, or browser-only APIs. Client components (marked `'use client'`) handle all interactivity.
Q: What is the `useId` hook?
A: `useId` (React 18+) generates a unique, stable ID that is consistent between server and client renders, solving the SSR hydration mismatch problem. It's designed for accessibility purposes — linking `
Q: [Scenario] How would you architect a large-scale React application?
A: Key decisions: 1) **State:** Local state with `useState`, server state with React Query / SWR, global UI state with Zustand or Redux Toolkit. 2) **Structure:** Feature-based folder structure (each feature is a self-contained module). 3) **Performance:** Route-level code splitting with `React.lazy`. 4) **Data fetching:** React Query for caching, deduplication, and background refetching. 5) **Rendering:** Next.js for SSR/SSG where SEO matters. 6) **Testing:** RTL for components, Jest for unit tests, Playwright for E2E.
Q: What is the `Suspense` component and how does it work with data fetching?
A: `}>` lets you display a loading state while its child component is 'suspended' (i.e., not ready to render). It was originally for `React.lazy` but in React 18 it integrates with data fetching libraries (React Query, Relay, Next.js) that 'throw a Promise' to signal loading. This allows components to declaratively show fallbacks without manually managing `isLoading` state.
Frequently Asked Questions
What version of React should I know for interviews in 2026?
React 18 is the current standard. Interviewers will expect you to know the Concurrent Features (startTransition, useDeferredValue), Automatic Batching, and the new Suspense improvements. Familiarity with Server Components (as used in Next.js 13+) is a strong differentiator.
Do I need to know Redux for a React interview?
Understanding Redux fundamentals (actions, reducers, store, middleware) is still expected at many companies. However, interviewers are increasingly interested in Zustand, Jotai, and React Query as modern alternatives. Knowing when to use Context vs. Redux is equally important.
How many hooks do I need to know?
At minimum: useState, useEffect, useRef, useMemo, useCallback, useContext, useReducer. For senior roles also know: useLayoutEffect, useId, useTransition, useDeferredValue, useImperativeHandle, and how to write robust custom hooks.
What is the most important React concept to understand for interviews?
The rendering and re-rendering model. Understanding exactly what causes a component to re-render (state change, parent re-render, context update), and how to prevent unnecessary re-renders (React.memo, useMemo, useCallback) is what separates strong candidates from average ones.
Are React class components still asked about in interviews?
Yes, especially at companies with legacy codebases. Know the lifecycle methods (componentDidMount, componentDidUpdate, componentWillUnmount) and understand how they map to useEffect. Knowing Error Boundaries is also important as they still require class components.
What is the difference between React and Next.js?
React is a UI library; Next.js is a full-stack framework built on top of React. Next.js provides routing, SSR, SSG, API routes, image optimization, and React Server Components out of the box. For senior frontend roles, expect questions on both.
What testing library is most commonly used with React?
React Testing Library (RTL) paired with Jest. RTL encourages testing components from the user's perspective — querying by accessible roles and text — rather than testing implementation details. Enzyme is considered legacy.
How should I prepare for a React live coding interview?
Practice building small, real-world components: a search bar with debounce, a TODO list with local storage, a data-fetching component with loading/error states. Focus on clean code, proper state management, and remembering `useCallback` when passing functions to memoized children.
How do I answer 'What is the Virtual DOM?' well?
The key is to explain the WHY, not just the WHAT. Say: 'Direct DOM manipulation is slow because it triggers layout reflows. React's VDOM is a fast, in-memory object representation. React diffs the new VDOM with the previous one, computes the minimal set of changes, and batches them into a single DOM update.' Then pause and ask if they want you to go deeper on the diffing algorithm.
Is TypeScript expected in React interviews?
Increasingly yes. Most production React codebases use TypeScript. Be comfortable with typing props (using interfaces), typing useState (useState(null)), and typing event handlers (React.ChangeEvent). Study our companion TypeScript interview questions for full preparation.