40 Questions

React Interview Questions for Freshers (2026)

calendar_todayLast Updated: June 2026verified_userReviewed by: PrepEdge Tech Editorial BoardscheduleReading time: ~15 mins

Prepare for your React developer interview with our curated collection of frequently asked questions. From fundamentals to advanced system scaling and architecture patterns — practice with AI-powered mock interviews that adapt to your skill level.

What is React and Why is it Critical in Modern Engineering?

React has emerged as a cornerstone of modern software development, specifically designed to address complex engineering and delivery challenges at scale. As a software engineer, preparing for a React technical interview for Freshers requires a structured, comprehensive understanding of its execution context, runtime performance, and underlying design philosophies. Master React interview questions. Practice with comprehensive beginner and experienced Q&A covering Virtual DOM & Reconciliation, Hooks Lifecycle, State Colocation, Concurrent Features, Server Components.

Focusing on the foundational core concepts, clean syntax, basic configuration, and fundamental programming interfaces is the absolute key to success for entry-level roles. Interviewers expect candidates to have a clear mental model and solid understanding of the basics without necessarily needing decades of system architecture experience. In this extensive guide, we dive deep into the top concepts, operational paradigms, and best practices that interviewers at top-tier companies look for. By mastering these interview questions and answers, you will not only pass the technical screening but also showcase real-world engineering mastery.

React Lifecycle Visualizer

StateTrigger ChangeVirtual DOM TreeRecompute nodesReconciliationO(N) DiffFiber Tree CompareReal DOMPAINT REFLOW

Click Simulate Flow to see Virtual DOM Reconciliation. State changes trigger virtual tree recomputes, which compare nodes via Fiber Diff and paint updates.

Core Architectural Concepts in React

When preparing for React technical interviews, you must demonstrate a deep command over its core building blocks. These are the fundamental abstractions that dictate how the technology behaves under heavy loads, concurrent workloads, and complex configurations:

Virtual DOM & Reconciliation

Instead of modifying the slow browser DOM directly, React compares in-memory trees to perform batch updates. In production, this prevents layout thrashing in high-frequency data tables.

Hooks Lifecycle

Hooks let functional components tap into state and lifecycle events. Building custom state hooks like useDebounce isolates user inputs to improve API querying efficiency.

State Colocation

Keeping state closest to where it is consumed limits rendering updates to the local subtree. This optimizes typing lag in multi-field nested forms.

Concurrent Features

Concurrent rendering permits pausing low-priority background renders to keep typing inputs responsive, using hooks like useDeferredValue to avoid thread locks.

Server Components

Server Components compile static content on the server, skipping hydration overhead and reducing client-side bundle size by keeping heavy markdown or date parsers server-side.

Having a theoretical understanding of these concepts is good, but being able to relate them to real-world projects, describing how you used them to solve actual performance issues or modularize code, will set you apart from other candidates.

check_circleWhy Modern Companies Choose React

  • checkBuilding responsive single-page applications (SPAs)
  • checkCreating reusable UI design systems and components
  • checkDeveloping high-performance client-side web interfaces

When explaining these points, always frame them around scalability, developer productivity, and overall cost of infrastructure. Interviewers love to see candidates who understand the direct connection between technical decisions and business outcomes.

lightbulbStrategic Preparation Tips

  • trending_flatMaster React reconciliation, fiber tree, and diffing algorithms.
  • trending_flatUnderstand hook dependency arrays and stale closure pitfalls.
  • trending_flatPractice profiling component renders and state batching behaviors.

Make sure to practice coding these scenarios under time constraints. Mock interviews are an excellent way to build confidence and refine your technical vocabulary. Focus on explaining *why* you chose a specific solution over alternatives, including the time and space complexity analysis.

errorCrucial Mistakes to Avoid

  • closeAvoid: Mutating state directly instead of using setState/reducers.
  • closeAvoid: Omitting key props or using array indices in dynamic lists.
  • closeAvoid: Declaring components inside other components, causing unmount resets.

Before jumping straight into coding or detailing a system design, always clarify requirements with your interviewer. This demonstrates a professional engineering workflow and prevents you from building the wrong solution.

trending_upHiring Trends & Career Outlook (2026)

Adoption of React Server Components (RSC) and server-side rendering. Streamlined transitions and actions using form actions. Transition away from heavy state libraries to atomic state stores.

The job market in 2026 demands highly capable engineers who understand security, performance, and distributed systems. Companies are actively looking for developers who can bridge the gap between frontend user interactivity, backend services, and database schemas. Staying ahead of these trends will position you for high-impact roles and competitive offers.

search

Basics

20 Questions

What is JSX and how does it differ from standard HTML template engines?

expand_more
EasyBasics
JSX (JavaScript XML) is a syntax extension for JavaScript that allows you to write HTML-like structures directly inside your JavaScript code. Unlike traditional template engines that separate logic from markup using proprietary syntax (like Handlebars or Angular templates), JSX compiles down to standard JavaScript function calls (React.createElement or new JSX runtime calls). This means that JSX is not merely a string template; it is a full JavaScript expression. Consequently, you have the full power of JavaScript (loops, conditionals, scope, variables) directly within your UI code. Here is a compilation target illustration:
// JSX source code
const element = <h1 className="title">Hello World</h1>;

// Compiled JavaScript code
const element = jsx('h1', { className: 'title', children: 'Hello World' });
Because of this design, JSX provides compile-time safety, auto-escapes values to prevent cross-site scripting (XSS) attacks, and integrates seamlessly with IDE autocompletion and static typing tools like TypeScript.

Explain the difference between Props and State, and when to use each.

expand_more
EasyBasics
Props (short for properties) and State are the two main types of data that control a React component, but they serve completely different architectural purposes: 1. Props are read-only (immutable) parameters passed down from a parent component to a child. They behave like function arguments, allowing parents to configure children dynamically. A child component must never modify its props directly, preserving the unidirectional data flow pattern of React. 2. State is a mutable, local data store managed entirely within the component itself. It represents the component's internal condition at any given point in time (e.g., whether a dropdown is open, or what text is entered in an input field). State updates trigger a re-render of the component and all its nested children. Here is a simple component showing both concepts:
interface ButtonProps {
  label: string; // prop
}

function ClickCounter({ label }: ButtonProps) {
  const [count, setCount] = useState(0); // state
  return (
    <button onClick={() => setCount(count + 1)}>
      {label}: {count}
    </button>
  );
}
As a rule of thumb, use props for data that originates outside the component or represents configuration, and use state for data that changes over time based on user interactions or async network updates within the component.

What is the Virtual DOM and how does React keep it in sync with the real DOM?

expand_more
EasyBasics
The Virtual DOM is a lightweight, in-memory representation of the real browser DOM. When a component's state or props change, React generates a new virtual tree of React elements. Instead of updating the expensive browser DOM immediately, React compares this new tree with the previous virtual DOM tree. This comparison process is called Reconciliation. React's diffing algorithm operates on two key assumptions to reduce comparison complexity from O(n³) to O(n): 1. Two elements of different HTML tags will produce different trees (React will destroy the old tree and mount a new one). 2. Developers can provide a stable 'key' prop to hint which child elements are stable across renders. Once the differences are calculated, React batches these changes and performs the minimal required writes to the real DOM in a single pass. This minimizes browser layout recalculations and repaints, which are the main bottlenecks of frontend performance.

What are React Hooks and why were they introduced in React 16.8?

expand_more
EasyBasics
React Hooks are functions that let you 'hook into' React state and lifecycle features from functional components. Before hooks, developers had to write ES6 class components to manage state and access lifecycles. Classes introduced several issues, such as complex binding of the this keyword, difficulties in reusing stateful logic without introducing nested patterns like Higher-Order Components (HOCs) or Render Props, and mixing unrelated code (like fetch logs and event listeners) inside single lifecycle methods like componentDidMount. Hooks resolved these paint points by allowing you to extract stateful logic into clean, reusable functions (custom hooks) that can be tested independently. The most common built-in hooks are: - useState for local state. - useEffect for side-effects (fetching, timers, subscriptions). - useContext for reading global context values. - useRef for persisting mutable values or referencing DOM elements.

How does state batching work in React 18 and what is automatic batching?

expand_more
EasyBasics
State batching is when React groups multiple state updates into a single re-render for better performance. Before React 18, React only batched updates inside React event handlers (like onClick). Updates inside promises, setTimeout, or native event handlers were not batched and triggered immediate sequential re-renders. React 18 introduced Automatic Batching, which batches all state updates regardless of where they originate:
// In React 18+, these updates trigger only ONE re-render:
fetch('/api').then(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
});
If you need to force an immediate render, you can opt out of batching using ReactDOM.flushSync(() => { ... }).

Why are keys necessary when rendering lists in React, and what happens if you use array indices?

expand_more
EasyBasics
Keys help React identify which items in a list have changed, been added, or been removed. During reconciliation, React matches the keys of the new virtual elements against the keys of the previous elements to determine if it can reuse the existing DOM nodes or if it must destroy and recreate them. Using array indices as keys is a dangerous antipattern. If the list is reordered, filtered, or prepended, the index key maps the state of the component incorrectly to the DOM elements. This leads to subtle UI bugs where input values, checkboxes, or CSS transitions remain attached to the wrong visual components. Always use a stable, unique identifier (like a database ID) as the key.

What is the difference between Functional Components and Class Components?

expand_more
EasyBasics
Functional components are JavaScript functions that accept props and return JSX. Class components are ES6 classes extending React.Component that require a render() method. Functional components are lightweight, compile to smaller bundles, and leverage React Hooks for stateful logic and side-effects. Class components manage state via this.state and lifecycles via methods like componentDidMount, which often leads to split logic and difficult code-sharing patterns. Modern React exclusively recommends functional components.

Explain Pure Components and React.memo in preventing unnecessary updates.

expand_more
EasyBasics
A Pure Component (in class-based React) automatically implements shouldComponentUpdate with a shallow prop and state comparison. In functional components, React.memo achieves the same optimization by wrapping a component and preventing it from re-rendering if its props have not changed.
const MyComponent = React.memo(function WrappedComponent(props) {
  return <div>{props.value}</div>;
});
If a parent component re-renders but passes the same props to MyComponent, React skips rendering the child entirely, protecting performance in large leaf node lists.

What is the difference between Controlled and Uncontrolled components in forms?

expand_more
EasyBasics
In controlled components, the form data is handled by a React component state. The input value is bound to the state, and every keystroke triggers an onChange handler that updates the state:
<input value={text} onChange={(e) => setText(e.target.value)} />
In uncontrolled components, form data is handled by the DOM itself. Instead of writing event handlers for every state update, you use a ref to pull values directly from the DOM when needed, which can be simpler for basic forms but harder for real-time validation.

Explain the React Context API and what problems it solves.

expand_more
EasyBasics
The Context API provides a way to pass data down the component tree without having to pass props manually at every level (a problem known as 'prop drilling'). It is useful for global states like themes, user authentication profiles, or localized language settings. However, it is not a complete state management replacement; any change to the Context provider's value forces all consumer components to re-render, which can lead to performance regressions in highly dynamic applications.

What is the children prop and how is it used for component composition?

expand_more
EasyBasics
The children prop is a special prop automatically passed to every component, representing the content enclosed between the component's opening and closing tags. It enables component composition, allowing you to build layouts that act as containers for generic content:
function Card({ children }) {
  return <div className="card-wrapper">{children}</div>;
}
This allows you to nest arbitrary HTML or other custom React components inside the container without coupling it to specific child components.

Explain the differences between handling events in React versus native HTML.

expand_more
EasyBasics
Event handling in React differs from native HTML in three main ways: 1. React events are named in camelCase (e.g., onClick) instead of lowercase (onclick). 2. With JSX, you pass a function reference instead of a string reference. 3. React wraps native browser events in a cross-browser wrapper called SyntheticEvent, which normalizes event behaviors across all browser platforms for consistent handling.

What are React Fragments and why are they preferred over wrapper divs?

expand_more
EasyBasics
React components must return a single root element. If you want to return multiple elements, wrapping them in a <div> inserts an extra node into the DOM tree, which can break CSS flexbox layouts, grid alignments, and semantic HTML markup. Fragments (<React.Fragment> or <>...</>) let you group a list of children without adding extra DOM nodes, resulting in a cleaner HTML footprint and faster page rendering speeds.

What is the purpose of StrictMode in React?

expand_more
EasyBasics
StrictMode is a development-only tool that highlights potential problems in an application. It does not render any visible UI. Instead, it activates checks and logs warnings for unsafe lifecycles, legacy API usages, and memory leaks. In React 18+, it intentionally mounts, unmounts, and remounts components twice to ensure side effects are idempotent and cleanup functions work properly.

What is prop drilling and how can it be avoided?

expand_more
EasyBasics
Prop drilling is the process of passing props through multiple levels of nested components simply to deliver the data to a deep child component, cluttering intermediate components. It can be avoided by reorganizing component trees (using component composition), using the Context API, or utilizing global state managers like Zustand, Jotai, or Redux.

What are defaultProps and propTypes in React?

expand_more
EasyBasics
propTypes is a runtime type-checking system for props in React development mode, allowing you to declare expected types and warn if incorrect props are sent. defaultProps defines default values for props if they are omitted by the parent. In modern React, ES6 default parameter values and TypeScript interfaces are preferred over these legacy systems.

How do you handle conditional rendering in React JSX?

expand_more
EasyBasics
Conditional rendering in React is done using standard JavaScript control structures: 1. Ternary operators for simple conditional elements: {isLoggedIn ? <UserMenu /> : <LoginButton />} 2. Logical && operators for rendering items if a condition is true: {hasError && <ErrorDisplay />} 3. Standard if-else or switch statements outside of the returned JSX block.

What is the role of the useEffect cleanup function?

expand_more
EasyBasics
The cleanup function returned by useEffect runs before the effect runs again and when the component unmounts. It is crucial for preventing memory leaks by clearing timers, unsubscribing from event listeners, terminating WebSockets, and aborting fetch calls:
useEffect(() => {
  const handler = () => console.log('resize');
  window.addEventListener('resize', handler);
  return () => window.removeEventListener('resize', handler); // cleanup
}, []);

How do you write and compile dynamic styles in React?

expand_more
EasyBasics
Dynamic styling in React is achieved using inline styles bound to state variables: <div style={{ color: isActive ? 'green' : 'red' }}> or by conditionally building CSS class names using template literals or utility libraries like clsx or tailwind-merge: <div className={btn ${isActive ? 'btn-active' : 'btn-inactive'}}>.

Explain how React devtools help inspect component state.

expand_more
EasyBasics
React Developer Tools is a browser extension that lets you inspect the React component tree. It displays the props, state, hooks, and context values of each component, and features a Profiler tab to record render frequencies, durations, and dependencies to pinpoint performance bottlenecks.

Testing

5 Questions

How do you design and test a custom hook using React Testing Library?

expand_more
MediumTesting
Testing custom hooks directly can be challenging because hooks cannot be invoked outside functional components. To test a hook, you must wrap it in a dummy component or use React Testing Library's built-in renderHook helper from @testing-library/react. Here is how you would write a test for a simple counter hook using Vitest and React Testing Library:
import { renderHook, act } from '@testing-library/react';
import { useCounter } from './useCounter';

test('should increment counter state', () => {
  // Render the hook in a virtual component container
  const { result } = renderHook(() => useCounter());
  
  expect(result.current.count).toBe(0);
  
  // State updates must be wrapped in act() block to ensure updates flush
  act(() => {
    result.current.increment();
  });
  
  expect(result.current.count).toBe(1);
});
When testing custom hooks that perform asynchronous actions (like fetching data), you should additionally use waitFor or result.current.loading assertions, and mock network requests using MSW (Mock Service Worker) to ensure tests remain isolated, reliable, and fast.

Explain how mock API calls are set up during integration testing.

expand_more
MediumTesting
To test component integration without hitting live servers, you mock API requests. Mock Service Worker (MSW) is the industry standard. It intercepts requests at the network layer using Service Workers in the browser or mock servers in Node, returning mocked JSON payloads for predictable, fast assertions.

How do you test error boundary components using test suites?

expand_more
MediumTesting
To test Error Boundaries, you simulate a rendering crash in a child component. In React Testing Library, you write a mock component that throws an error during render, wrap it in the Error Boundary, and assert that the fallback UI renders while suppressing expected console error logs.

What are the limitations of React Testing Library compared to E2E tests?

expand_more
MediumTesting
React Testing Library runs tests in a virtual DOM environment (jsdom) in Node. It cannot test real CSS layout engines, browser compatibility quirks, network latency, or full database database flows. End-to-End frameworks like Playwright or Cypress are required to validate real browser behaviors.

How do you mock local storage and browser variables in tests?

expand_more
MediumTesting
In Jest or Vitest, you mock browser globals using Object.defineProperty:
Object.defineProperty(window, 'localStorage', {
  value: { getItem: vi.fn(), setItem: vi.fn() }
});
This isolates testing code from browser engines and permits auditing storage triggers.

Performance

6 Questions

What is the difference between useMemo and useCallback, and how do they prevent performance regressions?

expand_more
MediumPerformance
Both useMemo and useCallback are optimization hooks that cache values between renders to prevent performance regressions, but they target different data types: 1. useMemo caches the *result* of a calculation. It executes a function and remembers its return value. It only recalculates when dependencies change.
const heavyCalculationValue = useMemo(() => {
  return expensiveCompute(data);
}, [data]);
2. useCallback caches the *function instance* itself. It returns the exact same function reference across renders instead of recreating it, preventing child components that receive the function as a prop from unnecessarily re-rendering.
const handleToggle = useCallback(() => {
  setOpen(prev => !prev);
}, []);
Both hooks have a memory overhead because they must keep references to dependencies and past computations in memory. Overusing them for simple computations can actually *hurt* performance. Use them when passing callbacks to memoized children (React.memo) or when dependencies trigger expensive downstream effects.

How does the reconciliation algorithm compare elements of different tags?

expand_more
MediumPerformance
React's diffing algorithm operates under the rule that if two elements are of different types (e.g., changing a <div> to a <p>), React will completely tear down the old component tree, unmount child nodes, destroy their local states, and build the new tree from scratch. This prevents React from attempting to patch mismatched HTML tags, optimizing layout transitions.

How do you detect and profile memory leaks in React components?

expand_more
MediumPerformance
Memory leaks typically occur when components set event listeners, timers, or WebSocket listeners and fail to clean them up on unmount. To profile them, use Chrome DevTools Memory tab, take Heap snapshots during repeated component mounts/unmounts, and search for 'detached' DOM elements and retained objects.

Explain the difference between useEffect and useLayoutEffect.

expand_more
MediumPerformance
useEffect runs asynchronously *after* the render is painted to the screen, which is ideal for standard side-effects like data fetching. useLayoutEffect runs synchronously *before* the browser paints the screen, making it necessary when measuring DOM layouts or adjusting positions to avoid layout flickering.

How does the Context Provider value optimization prevent re-renders?

expand_more
MediumPerformance
If a Context Provider passes a newly created object value, every render of the provider component generates a new reference, forcing all context consumers to re-render. To optimize this, memoize the context value using useMemo:
const value = useMemo(() => ({ user, status }), [user, status]);
return <UserContext.Provider value={value}>{children}</UserContext.Provider>;

How do you profile render durations using React DevTools?

expand_more
MediumPerformance
Using the React Profiler, click record and interact with the application. The profiler shows a 'flame chart' and a 'ranked chart' listing each component that rendered, how long it took, and the specific state or prop changes that triggered the update.

Architecture

9 Questions

Explain how code splitting and React.lazy() improve initial bundle load times.

expand_more
MediumArchitecture
By default, bundlers like Webpack or Vite compile all imports into a single, massive JavaScript file. If a user visits your homepage, they still have to download the code for settings pages, dashboards, and heavy charts, leading to slow Page Speed scores and high bounce rates. Code splitting divides this monolith into smaller chunks loaded on demand. In React, you achieve this using React.lazy() for dynamic imports, wrapped inside a <Suspense> boundary to show a fallback loading component while the chunk downloads:
import React, { lazy, Suspense } from 'react';

const HeavyDashboard = lazy(() => import('./HeavyDashboard'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading Dashboard...</div>}>
        <HeavyDashboard />
      </Suspense>
    </div>
  );
}
This ensures the code for HeavyDashboard is only fetched when the component is rendered, dramatically improving metrics like First Contentful Paint (FCP) and Time to Interactive (TTI).

Explain the Render Props pattern and when it is preferred over Hooks.

expand_more
MediumArchitecture
The Render Props pattern involves sharing stateful logic between components by using a prop whose value is a function. This function returns JSX, allowing the containing component to delegate UI rendering to the consumer:
<DataProvider render={(data) => <DisplayComponent data={data} />} />
While custom Hooks have largely replaced Render Props in modern codebases, Render Props remains useful when you need to share complex, stateful UI logic dynamically inside JSX, or when building flexible layouts in component libraries.

What are Higher-Order Components (HOCs) and how do they differ from hooks?

expand_more
MediumArchitecture
A Higher-Order Component (HOC) is a pure function that takes a component as an argument and returns an enhanced component, adding shared props or behaviors:
const AuthenticatedButton = withAuth(Button);
HOCs modify the component tree structure by wrapping elements, whereas Hooks share logic inside the component without adding wrapper nodes. Hooks are cleaner and avoid nesting issues, but HOCs are still powerful for cross-cutting layout overrides.

Explain Fiber node architecture and how it enables concurrent rendering.

expand_more
MediumArchitecture
React Fiber is the rendering engine introduced in React 16. It structures the component tree as a doubly linked list of 'Fiber' nodes. Each Fiber represents a unit of work. In older versions, rendering was synchronous and un-interruptible (blocking the main thread). Fiber allows React to split rendering work into small chunks, pause work to handle high-priority user inputs, and resume or discard work asynchronously, enabling Concurrent features.

What is the forwardRef API and when is it necessary?

expand_more
MediumArchitecture
Ref props cannot be passed to functional components directly because they are not standard props. forwardRef allows a component to expose its internal DOM nodes to its parent component:
const CustomInput = React.forwardRef((props, ref) => (
  <input ref={ref} {...props} />
));
This is necessary when parent components must direct DOM actions (like focusing, selecting, or measuring boundaries) on nested child inputs.

How does React portal work and what are its standard use cases?

expand_more
MediumArchitecture
Portals (ReactDOM.createPortal) let you render children into a DOM node that exists outside the parent component's hierarchy. This is crucial for UI overlays like modals, tooltips, and dropdowns to escape CSS overflows (overflow: hidden), z-index boundaries, and positioning context traps.

Explain component folder layout patterns in enterprise applications.

expand_more
MediumArchitecture
Enterprise codebases often organize folders by 'features' or 'domains' rather than generic layers. A features/billing/ directory would house its own local components, custom hooks, test suites, and state slices, while a global components/ directory handles reusable, stateless design UI primitives.

What is the useImperativeHandle hook and when should you use it?

expand_more
MediumArchitecture
useImperativeHandle is used with forwardRef to customize the instance value that is exposed to parent components, letting you expose restricted, custom helper methods instead of the raw DOM node to maintain abstraction boundaries.

Explain dynamic code splitting patterns using Webpack/Vite comments.

expand_more
MediumArchitecture
Bundlers allow you to define custom chunk names for dynamically imported files using inline comments: import(/* webpackChunkName: "charts" */ './Charts'). This groups related dynamic components into separate files, allowing the browser to cache them efficiently.

Questions for Other Experience Levels

Freshers (0-1 years)Current Page

Core fundamental concepts and frequently asked questions for entry-level developers.

Mid-Level (2-5 years)

Performance bottlenecks, debugging practices, and real-world project scenarios.

View Questions arrow_forward
Senior (5+ years)

Scale architecture, database design patterns, security, and production system design.

View Questions arrow_forward

Related Interview Topics

Practice React Interview Questions with AI

Reading answers is not enough. Practice explaining these concepts with PrepEdge's AI mock interviews and get surgical feedback on your responses.