Get interview-ready with the most frequently asked React interview questions, covering React fundamentals, Hooks, Components, State Management, Routing, Performance Optimization, Context API, Redux, and real-world coding challenges. Practice beginner to advanced questions commonly asked by top companies including Google, Microsoft, Amazon, Adobe, TCS, Infosys, Accenture, and more.
React is an open-source JavaScript library developed by Facebook (Meta) for building fast, interactive, and reusable user interfaces (UI).
Instead of updating the entire webpage, React updates only the parts that change, making applications much faster.
It is mainly used for building:
Single Page Applications (SPA)
Dashboards
Admin Panels
E-commerce websites
Social Media Apps
Chat Applications
The Virtual DOM (VDOM) is a lightweight copy of the real DOM stored in memory. Whenever the application's state or props change, React first updates the Virtual DOM instead of directly modifying the browser's DOM.
React then compares the new Virtual DOM with the previous one using a process called Diffing. After finding the differences, React updates only those elements that actually changed. This process is known as Reconciliation.
JSX stands for JavaScript XML. It is a syntax extension that allows us to write HTML-like code inside JavaScript.
Browsers cannot understand JSX directly. During compilation, Babel converts JSX into regular JavaScript using React.createElement().
React components can be created in two ways:
Functional Components
Class Components
Earlier, Class Components were used because they supported state and lifecycle methods. However, after React introduced Hooks, Functional Components became much more powerful and are now the recommended approach.
Functional Components
Simple JavaScript functions
Easier to understand
Less code
Use Hooks
Better performance
Recommended by React
Class Components
Use ES6 classes
Extend React.Component
Use lifecycle methods
More boilerplate code
Rarely used in new projects
Props (Properties) are used to pass data from a parent component to a child component.
Props are read-only, meaning the child component cannot modify them. They make components reusable because different data can be passed every time the component is used.
A Component is an independent and reusable piece of UI. Instead of writing one huge HTML page, React divides the application into multiple components like Navbar, Sidebar, Footer, Card, Login Form, etc.
Each component manages its own UI and logic, making code reusable and easier to maintain.
There are two main types:
Functional Components
Class Components
SPA stands for Single Page Application, while MPA stands for Multi Page Application.
In an SPA, the browser loads only one HTML page initially. After that, React updates the content dynamically without refreshing the entire page. This provides a faster and smoother user experience.
In an MPA, every navigation loads a completely new HTML page from the server.
SPA
One HTML page
Fast navigation
Better user experience
Uses React Router
MPA
Multiple HTML pages
Full page reload
Slower navigation
Traditional websites
A Fragment allows multiple elements to be returned from a component without adding an extra HTML element to the DOM.
Normally React components must return a single parent element. If you don't want an unnecessary <div>, you can use a Fragment.
Without Fragment
<div>
<h1>Hello</h1>
<p>React</p>
</div>
With Fragment
<>
<h1>Hello</h1>
<p>React</p>
</>
Keys are special attributes that help React uniquely identify each element in a list. They allow React to efficiently determine which items have been added, removed, or updated.
Without keys, React may re-render the entire list, leading to unnecessary updates and potential UI bugs.
A key should be unique among sibling elements. Using database IDs is recommended because they remain stable across renders. Using the array index as a key should generally be avoided if the list can change order, because it can cause incorrect updates.
const students = [
{ id: 1, name: "Kartik" },
{ id: 2, name: "Rahul" },
{ id: 3, name: "Amit" },
];
function App() {
return (
<ul>
{students.map((student) => (
<li key={student.id}>{student.name}</li>
))}
</ul>
);
}
useState is one of the most commonly used Hooks in React. It allows Functional Components to store and update data (state). Before Hooks were introduced in React 16.8, only Class Components could have state. Now, Functional Components can also manage state using useState.
Whenever the state changes using its setter function, React automatically re-renders the component so that the UI always displays the latest data.
The useState Hook returns an array containing two values:
The current state value.
A function to update that state.
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<h2>{count}</h2>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</>
);
}
useEffect is a React Hook used to perform side effects inside Functional Components.
A side effect is any operation that interacts with something outside the component, such as:
Calling an API
Fetching data
Setting timers
Updating the document title
Adding event listeners
Accessing localStorage
Without useEffect, these operations would execute during rendering, which can lead to unwanted behavior.
import { useEffect } from "react";
function App() {
useEffect(() => {
console.log("Component Mounted");
}, []);
return <h1>Hello React</h1>;
}
useRef is a React Hook that allows you to create a mutable reference that persists across renders without causing a re-render when its value changes.
It is commonly used for:
Accessing DOM elements directly
Storing previous values
Holding timers
Keeping mutable values that shouldn't trigger UI updates
Unlike useState, updating a ref does not re-render the component.
import { useRef } from "react";
function App() {
const inputRef = useRef();
const focusInput = () => {
inputRef.current.focus();
};
return (
<>
<input ref={inputRef} />
<button onClick={focusInput}>
Focus
</button>
</>
);
}
useMemo() is a React Hook used to memoize (cache) the result of an expensive calculation so that it is not recomputed on every render.
Normally, when a component re-renders, all calculations inside it run again, even if the input data hasn't changed. useMemo() stores the calculated value and only recalculates it when one of its dependencies changes. This helps improve performance, especially when dealing with large data sets or complex calculations.
import { useState, useMemo } from "react";
function App() {
const [count, setCount] = useState(0);
const [number, setNumber] = useState(5);
const square = useMemo(() => {
console.log("Calculating...");
return number * number;
}, [number]);
return (
<>
<h2>Square: {square}</h2>
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
<button onClick={() => setNumber(number + 1)}>
Change Number
</button>
</>
);
}
export default App;
Event handling in React is similar to JavaScript but uses camelCase event names, and event handlers are passed as functions instead of strings.
Common events include:
onClick
onChange
onSubmit
onMouseEnter
onMouseLeave
onKeyDown
function App() {
function showMessage() {
alert("Button Clicked");
}
return (
<button onClick={showMessage}>
Click Me
</button>
);
}
Output
Button Clicked
Conditional rendering means displaying different UI based on a condition. React uses normal JavaScript conditions like if, the ternary operator (? :), and logical AND (&&) to decide what to render.
function App() {
const isLoggedIn = true;
return (
<>
{
isLoggedIn
? <h1>Welcome User</h1>
: <h1>Please Login</h1>
}
</>
);
}
Output
Welcome User
A Controlled Component is a form element whose value is controlled by React state. The input value is stored in state, and every change updates that state.
Controlled components make validation, form submission, and state management easier.
import { useState } from "react";
function App() {
const [name, setName] = useState("");
return (
<>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<h2>{name}</h2>
</>
);
}
An Uncontrolled Component stores its data inside the DOM instead of React state. React accesses the value using a ref.
These components are generally used when integrating with third-party libraries or when React doesn't need to manage every input change.
import { useRef } from "react";
function App() {
const inputRef = useRef();
function showValue() {
alert(inputRef.current.value);
}
return (
<>
<input ref={inputRef} />
<button onClick={showValue}>
Submit
</button>
</>
);
}
useRef() creates a mutable object whose value persists between renders without causing the component to re-render when it changes.
It is commonly used for:
Accessing DOM elements
Managing focus
Storing timer IDs
Keeping previous values
Avoiding unnecessary re-renders
import { useRef } from "react";
function App() {
const inputRef = useRef();
function focusInput() {
inputRef.current.focus();
}
return (
<>
<input ref={inputRef} />
<button onClick={focusInput}>
Focus
</button>
</>
);
}
List rendering is the process of displaying multiple elements by iterating over an array. React commonly uses the JavaScript map() function to create a list of components.
Each element in the list should have a unique key prop to help React efficiently update only the changed items.
function App() {
const fruits = ["Apple", "Mango", "Orange"];
return (
<ul>
{
fruits.map((fruit, index) => (
<li key={index}>{fruit}</li>
))
}
</ul>
);
}
Output
• Apple
• Mango
• Orange
React Router is a library that enables client-side routing in React applications. Instead of reloading the entire page when navigating, React Router changes the displayed component while keeping the application running as a Single Page Application (SPA).
It provides components like BrowserRouter, Routes, Route, Link, and NavLink to define navigation and route mapping.
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function Home() {
return <h2>Home Page</h2>;
}
function About() {
return <h2>About Page</h2>;
}
function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link> |{" "}
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
useMemo() is a React Hook used to memoize (cache) the result of an expensive calculation. Normally, whenever a component re-renders, all functions inside it run again. If a calculation is complex (e.g., sorting a large array or filtering thousands of records), it can slow down the application.
useMemo() stores the calculated value and only recalculates it when its dependencies change. This improves performance by avoiding unnecessary computations.
import { useState, useMemo } from "react";
function App() {
const [count, setCount] = useState(0);
const square = useMemo(() => {
console.log("Calculating...");
return count * count;
}, [count]);
return (
<>
<h2>Count: {count}</h2>
<h2>Square: {square}</h2>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</>
);
}
useCallback() is used to memoize a function, whereas useMemo() memoizes a value.
useMemo | useCallback |
|---|
Returns a value | Returns a function |
Caches calculation | Caches function reference |
Used for expensive calculations | Used to prevent unnecessary child re-renders |
React.memo() is a Higher Order Component (HOC) that prevents a functional component from re-rendering if its props have not changed.
Normally, when a parent component re-renders, all child components also re-render. By wrapping a child component with React.memo(), React compares the previous props with the new props. If they are the same, React skips rendering that child component.
import React from "react";
const Child = React.memo(({ name }) => {
console.log("Child Rendered");
return <h2>{name}</h2>;
});
export default Child;
The Context API is a built-in React feature that allows data to be shared across multiple components without passing props manually through every intermediate component. This avoids prop drilling, where the same data has to be passed through several levels of components.
It is commonly used for global data such as authentication, themes, language preferences, and user information.
Prop Drilling is the process of passing data from a parent component to a deeply nested child through multiple intermediate components that do not actually need the data.
This makes the code harder to read and maintain.
A Custom Hook is a JavaScript function whose name starts with use. It allows developers to reuse stateful logic across multiple components instead of repeating the same code.
Custom Hooks help keep components clean, modular, and reusable.
Lazy Loading means loading a component only when it is needed instead of loading all components when the application starts. This reduces the initial bundle size and improves page loading speed.
React provides React.lazy() for lazy loading components.
A Higher-Order Component (HOC) is a function that takes a component as an argument and returns a new component with additional functionality. HOCs are used to reuse component logic without modifying the original component.
They are commonly used for authentication, logging, permissions, and data fetching. Although Hooks are preferred in modern React, you may still encounter HOCs in older codebases and interviews.
Hydration is the process where React attaches JavaScript event handlers to HTML that was already generated on the server.
Frameworks like Next.js use Server-Side Rendering (SSR) to send fully rendered HTML to the browser. Once the JavaScript bundle loads, React "hydrates" the page, making it interactive without rebuilding the entire UI.
Hydration improves:
SEO
Initial page load speed
User experience
Code Splitting is a performance optimization technique where the JavaScript bundle is divided into smaller chunks. Instead of downloading the entire application on the first page load, React loads only the code required for the current page.
This reduces the initial bundle size and improves loading performance.
Code Splitting is commonly implemented using React.lazy() and Suspense, or automatically by frameworks like Vite and Next.js.
Let's discuss how we can help you achieve your goals. Book a free 30-minute strategy call with our experts.