Top 25 React Interview Questions
Curated questions covering hooks, state management, virtual DOM, JSX, context, performance, and React patterns.
What is React and what are its key features?
React is a JavaScript library by Meta for building user interfaces. Key features: component-based architecture, virtual DOM for efficient updates, unidirectional data flow, JSX syntax, hooks for state and side effects, and a rich ecosystem.
What is the Virtual DOM and how does it work?
The Virtual DOM is an in-memory representation of the real DOM. When state changes, React creates a new virtual DOM tree, diffs it against the previous one (reconciliation), and applies only the minimal set of changes to the real DOM, making updates efficient.
What is JSX?
JSX (JavaScript XML) is a syntax extension that lets you write HTML-like code inside JavaScript. Babel compiles JSX to React.createElement() calls. JSX expressions must have a single root element and use className instead of class.
const element = <h1 className="title">Hello {name}</h1>;
// Compiles to:
const element = React.createElement("h1", { className: "title" }, "Hello ", name);
What is the difference between functional and class components?
- Class components — extend React.Component, use this.state and lifecycle methods. Verbose.
- Functional components — plain JavaScript functions. With hooks, they can manage state and side effects. Simpler and preferred.
- Hooks cannot be used in class components.
What are React hooks?
Hooks are functions that let functional components use state and lifecycle features. Rules: only call hooks at the top level (not inside loops/conditions), only call from React functions. Common hooks: useState, useEffect, useContext, useRef, useMemo, useCallback, useReducer.
What is useState?
useState returns a state variable and a setter function. Calling the setter triggers a re-render with the new value.
const [count, setCount] = useState(0);
const [user, setUser] = useState({ name: "", age: 0 });
// Update
setCount(prev => prev + 1);
setUser(prev => ({ ...prev, name: "Alice" }));
What is useEffect?
useEffect runs side effects after render. The dependency array controls when it runs: empty array = once on mount, with deps = when deps change, no array = every render. Return a cleanup function to run on unmount.
useEffect(() => {
const sub = subscribe(id);
return () => sub.unsubscribe(); // cleanup
}, [id]); // re-run when id changes
What is the difference between useMemo and useCallback?
- useMemo — memoises a computed value; re-computes only when dependencies change. Use for expensive calculations.
- useCallback — memoises a function reference; returns the same function unless dependencies change. Use to prevent child re-renders.
const total = useMemo(() => items.reduce((s, i) => s + i.price, 0), [items]);
const handleClick = useCallback(() => doSomething(id), [id]);
What is useRef?
useRef returns a mutable ref object whose .current property persists across renders without causing re-renders. Used for DOM access, storing previous values, and holding mutable values.
const inputRef = useRef(null);
useEffect(() => { inputRef.current.focus(); }, []);
return <input ref={inputRef} />;
What is the Context API?
Context provides a way to pass data through the component tree without prop drilling. Create a context with createContext(), provide it with Provider, and consume it with useContext().
const ThemeContext = createContext("light");
function App() {
return <ThemeContext.Provider value="dark"><Child /></ThemeContext.Provider>;
}
function Child() {
const theme = useContext(ThemeContext); // "dark"
}
What is prop drilling and how do you avoid it?
Prop drilling is passing props through multiple intermediate components that don't need them. Avoid it with: Context API, state management libraries (Redux, Zustand), component composition, or custom hooks.
What is the difference between controlled and uncontrolled components?
- Controlled — form element value is controlled by React state via value and onChange. Single source of truth.
- Uncontrolled — form element manages its own state; accessed via ref. Less React-idiomatic.
// Controlled
<input value={name} onChange={e => setName(e.target.value)} />
// Uncontrolled
const ref = useRef();
<input ref={ref} defaultValue="initial" />
What is React.memo?
React.memo is a higher-order component that memoises a functional component. It prevents re-rendering if props haven't changed (shallow comparison). Use for pure components that render often with the same props.
const Button = React.memo(({ label, onClick }) => (
<button onClick={onClick}>{label}</button>
));
What is useReducer?
useReducer is an alternative to useState for complex state logic. It takes a reducer function and initial state, returning current state and a dispatch function. Similar to Redux pattern.
function reducer(state, action) {
switch (action.type) {
case "increment": return { count: state.count + 1 };
default: return state;
}
}
const [state, dispatch] = useReducer(reducer, { count: 0 });
What are keys in React lists and why are they important?
Keys help React identify which items in a list have changed, been added, or removed. They must be unique among siblings. Using index as key is discouraged for dynamic lists as it can cause incorrect re-renders.
What is the difference between state and props?
- Props — passed from parent to child; read-only in the child; external data.
- State — managed within the component; mutable via setState/useState; triggers re-render when changed.
What is React.lazy and Suspense?
React.lazy enables code splitting by lazily loading components. Suspense shows a fallback UI while the lazy component loads.
const LazyPage = React.lazy(() => import("./LazyPage"));
<Suspense fallback={<Spinner />}>
<LazyPage />
</Suspense>
What is the React reconciliation algorithm?
Reconciliation is how React updates the DOM efficiently. React compares the new virtual DOM tree with the previous one using a diffing algorithm. It assumes elements of different types produce different trees and uses keys to match list items.
What are higher-order components (HOC)?
A HOC is a function that takes a component and returns a new enhanced component. Used for cross-cutting concerns like authentication, logging, and data fetching. Largely replaced by hooks in modern React.
function withAuth(Component) {
return function AuthComponent(props) {
if (!isLoggedIn) return <Redirect to="/login" />;
return <Component {...props} />;
};
}
What is the difference between useEffect and useLayoutEffect?
- useEffect — runs asynchronously after the browser paints. Use for most side effects.
- useLayoutEffect — runs synchronously after DOM mutations but before the browser paints. Use for DOM measurements and synchronous updates to avoid visual flicker.
What is Redux and when would you use it?
Redux is a predictable state management library. It uses a single store, pure reducer functions, and actions. Use it when: multiple components share complex state, state changes need to be traceable, or you need time-travel debugging. For simpler cases, Context + useReducer may suffice.
What is the StrictMode in React?
React.StrictMode is a development tool that highlights potential problems. It double-invokes render and lifecycle methods to detect side effects, warns about deprecated APIs, and detects unexpected side effects. Has no effect in production.
What is event delegation in React?
React attaches a single event listener to the root DOM node (not individual elements) and uses event bubbling to handle events. This is more efficient than attaching listeners to every element. React's synthetic event system normalises browser differences.
What are React portals?
Portals render children into a DOM node outside the parent component's DOM hierarchy. Useful for modals, tooltips, and overlays that need to escape overflow:hidden or z-index constraints.
ReactDOM.createPortal(
<Modal />,
document.getElementById("modal-root")
)
What is the difference between React 17 and React 18?
- React 18 introduced concurrent rendering with createRoot().
- Automatic batching — state updates in async code are now batched automatically.
- New hooks: useId, useTransition, useDeferredValue.
- Suspense improvements for data fetching.