Interview Preparation Checklist
React JS Interview Questions and Answers
Prepare for your next React JS interview with these frequently asked questions and detailed answers covering hooks, components, state management, props, lifecycle methods, and more.
Table of Contents
React, or ReactJS is an open-source front-end development library based on JavaScript. Facebook developed it, and it is now maintained by Meta Inc. and a vibrant community of developers. React uses a component-based architecture that consists of reusable, self-contained units called components, making the development of UI elements easy and efficient for developers.
Being one of the most popular front-end development libraries, React is a must-have skill in a front-end developer's arsenal. Below are some React interview questions and answers that can help you learn more about this front-end technology and prepare to face any interview for ReactJS.
React JS Basics
1. What is React JS? How does it differ from Angular JS? Beginner
React is a front-end and open-source JavaScript library that is useful for developing user interfaces, especially for applications with a single page. It helps build complex and reusable user interface components of mobile and web applications as it follows the component-based approach.
The important features of React are:
- It supports server-side rendering
- It will use the virtual DOM rather than the real DOM (Data Object Model) as RealDOM manipulations are expensive.
- It follows unidirectional data binding or data flow.
- It uses reusable or composable UI components for developing the view.
Example - A simple React component:
import React from 'react';
function App() {
return (
<div>
<h1>Hello, React!</h1>
<p>This is a React component.</p>
</div>
);
}
export default App;While AngularJS is a popular open-source framework that simplifies web development by creating interactive single-page applications.
Key Takeaway
React is a library (not a framework) focused solely on building UI. It uses a component-based architecture and Virtual DOM for efficient rendering.
Common Mistakes
- Confusing React with a full framework (it only handles the View layer)
- Saying React is the same as React Native (React Native is for mobile apps)
- Forgetting to mention Virtual DOM when explaining React benefits
Interview Tip
Most interviewers follow up with: Virtual DOM, JSX, and Component lifecycle. Be ready to explain how React differs from Angular (library vs framework, one-way vs two-way binding).
2. What are the benefits of using JSX in React JS? Beginner
Faster Development: JSX makes it faster to build and prototype components.
Better Performance: JSX helps avoid unnecessary DOM Updates, which can lead to improved performance in React JS Applications.
Improved code readability: JSX helps write code that is easier to understand, especially when working with nested components.
Example - JSX vs without JSX:
// With JSX
const element = <h1>Hello, World!</h1>;
// Without JSX (using React.createElement)
const element = React.createElement('h1', null, 'Hello, World!');3. How to create components in React? Beginner
Components are the building blocks of creating User Interfaces (UI) in React. There are two possible ways to create a component.
Function Components: This is the simplest way to create a component:
function Greeting({ message }) {
return <h1>{`Hello, ${message}`}</h1>;
}
// Usage
<Greeting message="React Developer" />Class Components: You can also use the ES6 class to define a component:
class Greeting extends React.Component {
render() {
return <h1>{`Hello, ${this.props.message}`}</h1>;
}
}
// Usage
<Greeting message="React Developer" />State and Props Interview Questions
4. How to distinguish states and props? What is the exact use of props and states in React JS? Beginner
States and props are both used to handle data in React components but they have differences in their functionalities.
States: Used to handle data within a component. It is mutable. We can modify the state data using the setState() function.
Props: Used to pass data from parent to child components. They are immutable (read-only) from the child component's perspective.
Example - Props vs State:
import { useState } from 'react';
function Parent() {
return <Child name="John" />;
}
function Child({ name }) {
const [count, setCount] = useState(0);
return (
<div>
<p>Hello {name} (from props)</p>
<p>Count: {count} (from state)</p>
<button onClick={() => setCount(count + 1)}>Add</button>
</div>
);
}5. What is the use of the state? Beginner
State is the simplest way to handle and store data in a React application. It allows for the creation of dynamic and responsive user interfaces.
Example - useState hook:
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}6. What are the features of the state? Beginner
- Enables re-rendering of components
- Changes dynamically
- Holds data
7. What is props drilling? Which is better - useContext or props? Intermediate
Props drilling refers to the process of passing data from a parent component to deeply nested child components. Each component in the hierarchy must pass the props down, even if only the last component in the chain needs the data.
Example - Props drilling problem:
function App() {
const user = "John";
return <Parent user={user} />;
}
function Parent({ user }) {
return <Child user={user} />;
}
function Child({ user }) {
return <p>Hello {user}</p>;
}Example - useContext solution:
import { createContext, useContext } from 'react';
const UserContext = createContext();
function App() {
return (
<UserContext.Provider value="John">
<Parent />
</UserContext.Provider>
);
}
function Parent() {
return <Child />;
}
function Child() {
const user = useContext(UserContext);
return <p>Hello {user}</p>;
}useContext is better for larger applications where multiple components need the same data. For simpler cases, passing props is fine.
Key Takeaway
Props drilling is passing data through multiple component layers. Use Context API for deeply nested data, but keep props for simple parent-child communication.
Interview Tip
Interviewers often ask this to test if you know state management patterns. Mention Context API, Redux, and Zustand as alternatives. Explain when each is appropriate.
React Hooks Interview Questions
8. What is a hook? What are major hooks? Beginner
React hooks are simple functions that allow functional components to use state, lifecycle methods, and other React features.
The major commonly used hooks are:
- useState - Manage local state
- useEffect - Handle side effects
- useContext - Access context values
- useReducer - Complex state logic
- useCallback - Memoize functions
- useMemo - Memoize computed values
- useRef - Access DOM elements or persist values
Example - useEffect hook:
import { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <p>Timer: {seconds}s</p>;
}Key Takeaway
Hooks let functional components use state and lifecycle features. useState and useEffect are the two most important hooks you must know.
Common Mistakes
- Using class components when hooks can solve the problem simpler
- Forgetting the dependency array in useEffect (causes infinite loops)
- Not cleaning up effects (memory leaks)
Interview Tip
Be prepared to write a custom hook on the spot. Common follow-ups: useCallback vs useMemo, when to use useReducer over useState, and how to share logic between components.
9. What are the rules that must be followed when using hooks in React JS? Beginner
When using hooks in React JS we need to follow some important rules to avoid bugs:
- Always call hooks at the top level of the program
- Import the hook (import {useState} from 'react')
- Do not call hooks inside loops, conditions, or nested functions
- Only call hooks inside React functions
- Add dependency arrays for useEffect and similar hooks
Example - Wrong vs Right:
// WRONG - hook inside condition
function App() {
if (true) {
const [count, setCount] = useState(0); // Error!
}
}
// RIGHT - hook at top level
function App() {
const [count, setCount] = useState(0);
if (count > 5) {
// conditional logic here is fine
}
}Lifecycle & Advanced React Interview Questions
10. Explain the lifecycle methods in React JS. Intermediate
Here are some popular lifecycle methods for enhancing and modifying components' behaviour:
- componentDidMount() - Called after the component is rendered to the DOM
- componentDidUpdate() - Called after a component re-renders due to state/prop changes
- componentWillUnmount() - Called before a component is removed from the DOM
- shouldComponentUpdate() - Determines if a re-render is needed
Example - Lifecycle in class component:
class UserProfile extends React.Component {
componentDidMount() {
console.log("Component mounted");
}
componentDidUpdate(prevProps) {
if (prevProps.userId !== this.props.userId) {
console.log("User ID changed");
}
}
componentWillUnmount() {
console.log("Component unmounting");
}
render() {
return <h1>User: {this.props.userId}</h1>;
}
}Equivalent using hooks (modern approach):
import { useEffect } from 'react';
function UserProfile({ userId }) {
useEffect(() => {
console.log("Mounted / userId changed");
return () => console.log("Cleanup");
}, [userId]);
return <h1>User: {userId}</h1>;
}11. Explain types of side effects in React components. Intermediate
In React, a side effect is any action like data fetching or DOM manipulation that affects something outside the component's rendering process. React uses the useEffect hook to handle side effects.
Side effects can be categorized as:
- Mounting Side Effects: Occur on first render. Examples: data fetching, subscriptions, timers.
- Updating Side Effects: Happen when props or state changes.
- Cleaning Up Side Effects: Needed to avoid memory leaks when component unmounts.
Example - All three types:
import { useState, useEffect } from 'react';
function DataFetcher({ url }) {
const [data, setData] = useState(null);
useEffect(() => {
console.log("Fetching data...");
fetch(url)
.then(res => res.json())
.then(json => setData(json));
return () => console.log("Cleaning up...");
}, [url]);
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}12. What are higher-order components? Advanced
Higher-order components (HOCs) in React are a pattern used for reusing component logic. A HOC is a function that takes a component as input and returns a new component with additional functionality.
Example - HOC that adds loading state:
function withLoading(WrappedComponent) {
return function({ isLoading, ...props }) {
if (isLoading) {
return <p>Loading...</p>;
}
return <WrappedComponent {...props} />;
};
}
function UserList({ users }) {
return (
<ul>
{users.map(u => <li key={u.id}>{u.name}</li>)}
</ul>
);
}
const UserListWithLoading = withLoading(UserList);
// Usage
<UserListWithLoading isLoading={true} users={[]} />
<UserListWithLoading isLoading={false} users={[{id:1, name:"John"}]} />Virtual DOM and Rendering
13. What is Virtual DOM? How does it work? Intermediate
The Virtual DOM is a lightweight JavaScript representation of the actual DOM. React creates a virtual copy of the DOM in memory and uses a diffing algorithm to compare changes before updating the real DOM.
How it works:
- When state changes, React creates a new Virtual DOM tree
- It compares (diffs) the new tree with the previous one
- Only the changed elements are updated in the real DOM (reconciliation)
Example:
function Counter() {
const [count, setCount] = useState(0);
// Only the <span> with count re-renders,
// not the entire component tree
return (
<div>
<h1>My Counter App</h1>
<span>{count}</span>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}14. What is the difference between Virtual DOM and Real DOM? Intermediate
| Virtual DOM | Real DOM |
|---|---|
| Lightweight copy in memory | Actual browser DOM |
| Updates are batched and fast | Updates are slow and expensive |
| Cannot directly update HTML | Directly updates HTML |
| Uses diffing algorithm | Re-renders entire tree on change |
| Minimal memory usage per update | High memory consumption |
15. What is reconciliation in React? Intermediate
Reconciliation is the process React uses to update the DOM efficiently. When a component's state or props change, React compares the new Virtual DOM with the previous one and calculates the minimum number of operations needed to update the real DOM.
Key rules React follows:
- Elements of different types produce different trees (full re-render)
- The developer can hint which elements are stable using the
keyprop - React only updates the attributes that changed on same-type elements
16. What is the key prop and why is it important? Intermediate
The key prop is a special attribute used when rendering lists. It helps React identify which items have changed, been added, or removed.
Example - Without vs With key:
// WRONG - no key
function TodoList({ todos }) {
return (
<ul>
{todos.map(todo => <li>{todo.text}</li>)}
</ul>
);
}
// RIGHT - with unique key
function TodoList({ todos }) {
return (
<ul>
{todos.map(todo => <li key={todo.id}>{todo.text}</li>)}
</ul>
);
}Components - Advanced Concepts
17. What are controlled and uncontrolled components? Intermediate
Controlled components have their form data handled by React state. Uncontrolled components store form data in the DOM itself.
Controlled component example:
function ControlledForm() {
const [name, setName] = useState("");
return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
}Uncontrolled component example:
function UncontrolledForm() {
const inputRef = useRef(null);
const handleSubmit = () => {
alert(inputRef.current.value);
};
return (
<div>
<input ref={inputRef} />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}18. What is conditional rendering in React? Beginner
Conditional rendering means displaying different UI based on certain conditions, similar to how conditions work in JavaScript.
Common patterns:
function Dashboard({ isLoggedIn, isAdmin }) {
// 1. if/else
if (!isLoggedIn) {
return <p>Please log in</p>;
}
// 2. Ternary operator
return (
<div>
{isAdmin ? <AdminPanel /> : <UserPanel />}
{/* 3. Logical AND (short-circuit) */}
{isAdmin && <p>Admin controls visible</p>}
</div>
);
}19. What are Pure Components in React? Intermediate
A Pure Component only re-renders when its props or state actually change. In class components, use React.PureComponent. In functional components, use React.memo().
Example:
// Functional pure component using React.memo
const UserCard = React.memo(function({ name, age }) {
console.log("Rendering UserCard");
return (
<div>
<h3>{name}</h3>
<p>Age: {age}</p>
</div>
);
});
// Parent component
function App() {
const [count, setCount] = useState(0);
return (
<div>
<UserCard name="John" age={25} />
<button onClick={() => setCount(count + 1)}>Count: {count}</button>
</div>
);
}20. What are Error Boundaries in React? Advanced
Error Boundaries are React components that catch JavaScript errors in their child component tree, log them, and display a fallback UI instead of crashing the whole application.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.log("Error caught:", error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h2>Something went wrong.</h2>;
}
return this.props.children;
}
}
// Usage
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>Common Mistakes
- Trying to use Error Boundaries with hooks (they only work as class components)
- Not placing Error Boundaries at meaningful levels (too high = generic error, too low = too many boundaries)
- Forgetting that Error Boundaries do NOT catch errors in event handlers, async code, or SSR
Interview Tip
Mention that React does not have hook-based error boundaries yet. Libraries like react-error-boundary provide a hook-based API. Always explain where you would place them in a real app.
21. What is React.lazy() and Suspense? Advanced
React.lazy() allows you to load components lazily (on demand), reducing the initial bundle size. Suspense shows a fallback UI while the lazy component loads.
import React, { Suspense, lazy } from 'react';
// Lazy load the component
const HeavyChart = lazy(() => import('./HeavyChart'));
function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
<Suspense fallback={<p>Loading chart...</p>}>
<HeavyChart />
</Suspense>
</div>
);
}22. What are fragments in React? Beginner
Fragments let you group multiple elements without adding extra DOM nodes. This avoids unnecessary wrapper divs.
// Without Fragment (adds extra div)
function WithDiv() {
return (
<div>
<h1>Title</h1>
<p>Content</p>
</div>
);
}
// With Fragment (no extra DOM node)
function WithFragment() {
return (
<>
<h1>Title</h1>
<p>Content</p>
</>
);
}Advanced Hooks Interview Questions
23. What is useReducer? When should you use it instead of useState? Intermediate
useReducer is a hook for managing complex state logic. Use it when state has multiple sub-values or when the next state depends on the previous one.
import { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
case 'reset':
return { count: 0 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
<button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
</div>
);
}24. What is useRef? What are its common use cases? Intermediate
useRef creates a mutable reference that persists across renders without causing re-renders when changed.
Common use cases:
- Accessing DOM elements directly
- Storing previous values
- Keeping mutable values that do not trigger re-renders
import { useRef, useEffect } from 'react';
function AutoFocusInput() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus(); // Focus input on mount
}, []);
return <input ref={inputRef} placeholder="Auto-focused!" />;
}25. What is useCallback and when should you use it? Advanced
useCallback memoizes a function so it is not recreated on every render. Use it when passing callbacks to child components that rely on reference equality to prevent unnecessary re-renders.
import { useState, useCallback } from 'react';
function Parent() {
const [count, setCount] = useState(0);
// Without useCallback: new function on every render
// const handleClick = () => setCount(count + 1);
// With useCallback: same function reference
const handleClick = useCallback(() => {
setCount(prev => prev + 1);
}, []);
return <Child onClick={handleClick} />;
}
const Child = React.memo(({ onClick }) => {
console.log("Child rendered");
return <button onClick={onClick}>Click</button>;
});26. What is useMemo and how does it differ from useCallback? Advanced
useMemo memoizes a computed value. useCallback memoizes a function. Use useMemo for expensive calculations that should not re-run on every render.
import { useState, useMemo } from 'react';
function ExpensiveList({ items, filter }) {
// Only recalculates when items or filter change
const filteredItems = useMemo(() => {
console.log("Filtering...");
return items.filter(item => item.includes(filter));
}, [items, filter]);
return (
<ul>
{filteredItems.map(item => <li key={item}>{item}</li>)}
</ul>
);
}27. How to create a custom hook in React? Intermediate
A custom hook is a JavaScript function starting with "use" that can call other hooks. It lets you extract reusable logic from components.
import { useState, useEffect } from 'react';
// Custom hook
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
// Usage in any component
function Header() {
const width = useWindowWidth();
return <p>Window width: {width}px</p>;
}React Router and Event Handling
28. What is React Router? How do you implement routing? Intermediate
React Router is a library for handling navigation in React applications. It enables single-page applications to have multiple views without full page reloads.
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}29. How does event handling work in React? Intermediate
React uses synthetic events - a cross-browser wrapper around native events. Events are named in camelCase and you pass functions (not strings) as handlers.
function EventExamples() {
const handleClick = (e) => {
e.preventDefault(); // Works same as native
console.log("Button clicked");
};
const handleChange = (e) => {
console.log("Input value:", e.target.value);
};
return (
<div>
<button onClick={handleClick}>Click Me</button>
<input onChange={handleChange} />
</div>
);
}30. What is event bubbling in React? How to stop it? Intermediate
Event bubbling means when an event occurs on an element, it propagates up through its parent elements. Use e.stopPropagation() to prevent it.
function BubblingExample() {
return (
<div onClick={() => console.log("Parent clicked")}>
<button onClick={(e) => {
e.stopPropagation(); // Prevents parent handler
console.log("Button clicked");
}}>
Click Me
</button>
</div>
);
}React Performance Optimization
31. How to optimize performance in React applications? Advanced
Key techniques for optimizing React performance:
- React.memo() - Prevent unnecessary re-renders of functional components
- useMemo / useCallback - Memoize values and functions
- Code splitting - Use React.lazy() and dynamic imports
- Virtualization - Render only visible list items (react-window)
- Avoid inline objects/functions - They create new references every render
- Use keys properly - Stable, unique keys for lists
32. What causes unnecessary re-renders and how to prevent them? Advanced
Common causes of unnecessary re-renders:
- Parent component re-rendering (all children re-render by default)
- Creating new objects/arrays/functions in render
- Not using React.memo for pure components
- Context value changing (all consumers re-render)
// Problem: new object on every render
function App() {
const [count, setCount] = useState(0);
// This creates a new style object every render:
return <Child style={{ color: "red" }} />;
}
// Solution: memoize or define outside
const style = { color: "red" }; // defined once
function App() {
const [count, setCount] = useState(0);
return <Child style={style} />;
}State Management
33. What is Redux? When should you use it? Intermediate
Redux is a predictable state management library. Use it when your application has complex state shared across many components and prop drilling becomes impractical.
Core concepts:
- Store - Single source of truth for application state
- Actions - Objects describing what happened
- Reducers - Pure functions that specify how state changes
- Dispatch - Method to send actions to the store
// Action
const increment = { type: 'INCREMENT' };
// Reducer
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
}
// Usage in component
function Counter() {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
return (
<div>
<p>{count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
</div>
);
}Key Takeaway
Redux = predictable state container. Use it for complex apps with lots of shared state. For simpler apps, Context API or Zustand may be better choices.
Common Mistakes
- Using Redux for everything (overkill for small apps)
- Mutating state directly in reducers instead of returning new objects
- Not using Redux Toolkit (modern Redux) and writing too much boilerplate
Interview Tip
Modern interviews expect you to know Redux Toolkit, not legacy Redux. Also compare with alternatives: Zustand, Jotai, Recoil. Explain the one-way data flow: Action -> Reducer -> Store -> View.
34. What is the Context API? How does it compare to Redux? Advanced
The Context API is built into React for passing data through the component tree without prop drilling. It is simpler than Redux but less suited for high-frequency updates.
| Context API | Redux |
|---|---|
| Built into React | External library |
| Simple setup | More boilerplate |
| Good for low-frequency updates (theme, auth) | Good for frequent, complex state changes |
| All consumers re-render on value change | Only subscribed components re-render |
| No middleware support | Supports middleware (thunk, saga) |
35. What is lifting state up in React? Intermediate
Lifting state up means moving state to the closest common ancestor of components that need to share it. This is the React pattern for sharing state between sibling components.
function Parent() {
const [temperature, setTemperature] = useState("");
return (
<div>
<CelsiusInput temp={temperature} onTempChange={setTemperature} />
<FahrenheitDisplay temp={temperature} />
</div>
);
}
function CelsiusInput({ temp, onTempChange }) {
return <input value={temp} onChange={e => onTempChange(e.target.value)} />;
}
function FahrenheitDisplay({ temp }) {
const fahrenheit = temp ? (parseFloat(temp) * 9/5 + 32).toFixed(1) : "";
return <p>Fahrenheit: {fahrenheit}</p>;
}Forms and Data Fetching
36. How to handle forms in React? Intermediate
In React, form inputs are typically handled as controlled components where React state drives the input values.
function LoginForm() {
const [formData, setFormData] = useState({
email: "",
password: ""
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log("Submitted:", formData);
};
return (
<form onSubmit={handleSubmit}>
<input name="email" value={formData.email} onChange={handleChange} />
<input name="password" type="password" value={formData.password} onChange={handleChange} />
<button type="submit">Login</button>
</form>
);
}37. How to fetch data from an API in React? Intermediate
Use the useEffect hook combined with fetch or axios to load data when a component mounts.
import { useState, useEffect } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then(res => {
if (!res.ok) throw new Error("Failed to fetch");
return res.json();
})
.then(data => {
setUsers(data);
setLoading(false);
})
.catch(err => {
setError(err.message);
setLoading(false);
});
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
}38. What is the difference between useEffect and useLayoutEffect? Intermediate
useEffect runs asynchronously after the browser paints. useLayoutEffect runs synchronously before the browser paints.
| useEffect | useLayoutEffect |
|---|---|
| Runs after paint | Runs before paint |
| Non-blocking (async) | Blocking (sync) |
| Use for data fetching, subscriptions | Use for DOM measurements, preventing flicker |
| Preferred in most cases | Use only when needed |
import { useLayoutEffect, useRef } from 'react';
function Tooltip() {
const ref = useRef();
// Use useLayoutEffect to measure DOM before user sees it
useLayoutEffect(() => {
const { height } = ref.current.getBoundingClientRect();
console.log("Element height:", height);
// Position tooltip based on measurement
}, []);
return <div ref={ref}>Tooltip content</div>;
}Testing and Design Patterns
39. How to test React components? Advanced
React components are commonly tested using React Testing Library along with Jest. The approach focuses on testing behavior from the user's perspective.
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('increments counter on button click', () => {
render(<Counter />);
// Find elements like a user would
const button = screen.getByText("Click me");
const count = screen.getByText("You clicked 0 times");
// Simulate user action
fireEvent.click(button);
// Assert the result
expect(screen.getByText("You clicked 1 times")).toBeInTheDocument();
});40. What are render props in React? Intermediate
Render props is a pattern where a component receives a function as a prop that returns a React element. It allows sharing behavior between components.
// Component with render prop
function MouseTracker({ render }) {
const [position, setPosition] = useState({ x: 0, y: 0 });
const handleMouseMove = (e) => {
setPosition({ x: e.clientX, y: e.clientY });
};
return (
<div onMouseMove={handleMouseMove} style={{ height: "100vh" }}>
{render(position)}
</div>
);
}
// Usage
<MouseTracker render={({ x, y }) => (
<p>Mouse position: {x}, {y}</p>
)} />41. What is the difference between class components and functional components? Intermediate
| Class Components | Functional Components |
|---|---|
| Use ES6 class syntax | Use plain JavaScript functions |
| Have lifecycle methods | Use hooks (useEffect) |
| Use this.state and this.setState | Use useState hook |
| Can have refs directly | Use useRef hook |
| More boilerplate code | Cleaner, less code |
| Harder to reuse logic | Custom hooks for reusable logic |
Modern React recommends functional components with hooks for all new code.
42. What is the spread operator and how is it used in React? Beginner
The spread operator (...) is used to pass all properties of an object as individual props, copy objects/arrays immutably, and merge state updates.
// Passing all props
const buttonProps = { type: "submit", className: "btn", disabled: false };
<button {...buttonProps}>Submit</button>
// Immutable state update
const [user, setUser] = useState({ name: "John", age: 25, city: "NYC" });
// Update only age, keep rest unchanged
setUser(prev => ({ ...prev, age: 26 }));
// Result: { name: "John", age: 26, city: "NYC" }Modern React (2025-2026)
43. What are React Server Components? Advanced
React Server Components (RSC) are components that render on the server and send only the HTML to the client. They reduce JavaScript bundle size and improve initial load performance.
Key differences from client components:
- Cannot use hooks (useState, useEffect)
- Cannot use browser APIs
- Can directly access databases and file systems
- Send zero JavaScript to the client
- Use "use server" directive
// Server Component (default in Next.js App Router)
async function UserProfile({ userId }) {
// Can fetch directly - no useEffect needed
const user = await db.query("SELECT * FROM users WHERE id = $1", [userId]);
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
// Client Component (needs interactivity)
"use client";
function LikeButton() {
const [liked, setLiked] = useState(false);
return <button onClick={() => setLiked(!liked)}>{liked ? "Liked" : "Like"}</button>;
}Interview Tip
This is a hot topic in 2026 interviews. Know the difference between Server and Client Components, when to use "use client", and how frameworks like Next.js implement RSC.
44. What is the useTransition hook? Advanced
useTransition lets you mark state updates as non-urgent transitions. The UI remains responsive during expensive re-renders by keeping the old UI visible until the new one is ready.
import { useState, useTransition } from 'react';
function SearchResults() {
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);
const [isPending, startTransition] = useTransition();
const handleChange = (e) => {
setQuery(e.target.value); // urgent: update input immediately
startTransition(() => {
// non-urgent: can be interrupted
setResults(filterLargeList(e.target.value));
});
};
return (
<div>
<input value={query} onChange={handleChange} />
{isPending && <p>Updating...</p>}
<ul>{results.map(r => <li key={r}>{r}</li>)}</ul>
</div>
);
}45. What is React.forwardRef? Intermediate
forwardRef lets a component pass a ref to a child component. This is needed because refs cannot be passed as regular props.
import { forwardRef, useRef } from 'react';
// Child component that accepts a ref
const CustomInput = forwardRef(function(props, ref) {
return <input ref={ref} placeholder={props.placeholder} />;
});
// Parent component
function Form() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<CustomInput ref={inputRef} placeholder="Type here..." />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}46. What is the difference between useMemo and React.memo? Intermediate
They solve different problems:
| React.memo | useMemo |
|---|---|
| Higher-order component | Hook |
| Memoizes entire component rendering | Memoizes a computed value |
| Prevents re-render if props unchanged | Prevents recalculation if dependencies unchanged |
| Wraps component: React.memo(MyComp) | Used inside component: useMemo(() => calc(), [deps]) |
// React.memo - prevents component re-render
const ExpensiveList = React.memo(function({ items }) {
return items.map(i => <li key={i.id}>{i.name}</li>);
});
// useMemo - prevents value recalculation
function Dashboard({ data }) {
const total = useMemo(() => {
return data.reduce((sum, item) => sum + item.price, 0);
}, [data]);
return <p>Total: ${total}</p>;
}47. What is StrictMode in React? Beginner
StrictMode is a development-only tool that highlights potential problems in your application. It does not render any visible UI and does not affect production builds.
What it detects:
- Unsafe lifecycle methods
- Legacy string ref usage
- Side effects in render phase (double-invokes components)
- Deprecated APIs
import { StrictMode } from 'react';
function App() {
return (
<StrictMode>
<MainContent />
</StrictMode>
);
}48. What is the useId hook? Beginner
useId generates unique IDs that are stable across server and client rendering. It solves the problem of ID mismatches during hydration in SSR apps.
import { useId } from 'react';
function FormField({ label }) {
const id = useId();
return (
<div>
<label htmlFor={id}>{label}</label>
<input id={id} type="text" />
</div>
);
}
// Using multiple times generates unique IDs
<FormField label="Name" /> // id=":r1:"
<FormField label="Email" /> // id=":r2:"49. What is prop types validation in React? Beginner
PropTypes is a runtime type-checking library for React props. It warns in development if a component receives props of the wrong type.
import PropTypes from 'prop-types';
function UserCard({ name, age, isAdmin }) {
return (
<div>
<h3>{name}</h3>
<p>Age: {age}</p>
{isAdmin && <span>Admin</span>}
</div>
);
}
UserCard.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
isAdmin: PropTypes.bool
};
UserCard.defaultProps = {
isAdmin: false
};Interview Tip
While PropTypes still works, most companies now use TypeScript for type safety. Mention both approaches and explain why TypeScript is preferred (compile-time vs runtime checking).
50. What is React Portals? Intermediate
Portals let you render children into a DOM node outside the parent component's DOM hierarchy. This is commonly used for modals, tooltips, and dropdown menus.
import { createPortal } from 'react-dom';
function Modal({ children, isOpen }) {
if (!isOpen) return null;
return createPortal(
<div className="modal-overlay">
<div className="modal-content">
{children}
</div>
</div>,
document.getElementById('modal-root') // renders outside #app-root
);
}
// Usage
function App() {
const [showModal, setShowModal] = useState(false);
return (
<div>
<button onClick={() => setShowModal(true)}>Open</button>
<Modal isOpen={showModal}>
<p>This renders outside the App DOM tree!</p>
</Modal>
</div>
);
}Common Mistakes
- Forgetting to add the portal target element in index.html
- Not handling keyboard events (Escape to close) for accessibility
- Not trapping focus inside the modal
51. What is the difference between useEffect and event handlers? Intermediate
Event handlers run in response to user actions (clicks, typing). useEffect runs after render to synchronize with external systems.
| Event Handlers | useEffect |
|---|---|
| Triggered by user action | Triggered by rendering |
| Run specific code on interaction | Synchronize with external system |
| E.g., submit form, navigate | E.g., fetch data, set up subscription |
| No cleanup needed | May need cleanup function |
function ChatRoom({ roomId }) {
// Event handler: runs when user clicks
const sendMessage = () => {
postMessage(roomId, message);
};
// Effect: synchronize with chat server
useEffect(() => {
const connection = createConnection(roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);
return <button onClick={sendMessage}>Send</button>;
}52. How to prevent prop drilling without Context or Redux? Intermediate
Alternative patterns to avoid prop drilling:
- Component Composition - Pass components as children instead of data
- Render Props - Pass a function that returns JSX
- Custom Hooks - Share logic without passing props
- URL State - Store state in URL params (React Router)
// Component Composition (best alternative)
// Instead of passing user through 3 levels:
function App() {
const user = useUser();
return (
<Layout>
<Header>
<UserAvatar name={user.name} />
</Header>
<Sidebar>
<UserMenu permissions={user.permissions} />
</Sidebar>
</Layout>
);
}
// Layout and Sidebar never know about user!
function Layout({ children }) {
return <div className="layout">{children}</div>;
}
function Sidebar({ children }) {
return <aside>{children}</aside>;
}Interview Tip
Component composition is the React team's recommended solution before reaching for Context. Show that you understand the tradeoffs: composition for UI structure, Context for truly global data (theme, auth), Redux for complex state machines.
Official Resources & Further Reading
To dive deeper into React JS concepts covered in this interview guide, refer to these official and authoritative resources:
- React Official Documentation - The official React docs with guides, API reference, and tutorials.
- React Learn - Quick Start Guide - Official step-by-step tutorial for beginners.
- React Hooks API Reference - Complete reference for all built-in hooks (useState, useEffect, useContext, etc.)
- Managing State in React - Official guide on state management patterns.
- Redux Toolkit Documentation - Modern Redux with less boilerplate.
- React Router Documentation - Official routing library for React applications.
- React Testing Library - Testing utilities for React components.
Tip: Bookmark the React Blog to stay updated with the latest React releases, features, and best practices.