A set of React interview questions and answers, updated for modern React (2026).
- What is React?
Answer
React is an open-source JavaScript library created by Meta (formerly Facebook) for building user interfaces. It focuses exclusively on the UI layer, making it flexible enough to integrate with any backend or tooling.
React uses a component-based architecture where you build your UI as a tree of reusable, composable components. Each component manages its own rendering logic, making complex UIs easier to reason about.
- What is the Virtual DOM and how does it work?
Answer
The Virtual DOM is a lightweight, in-memory representation of the actual DOM. When a component's state or props change, React creates a new Virtual DOM tree and compares it with the previous one — a process called reconciliation (or "diffing").
React then calculates the minimal set of changes needed and applies only those updates to the real DOM. This makes updates efficient because direct DOM manipulation is expensive, and React batches and minimizes those operations.
- The Virtual DOM is not the same as the Shadow DOM (a browser API for encapsulation).
- React's diffing algorithm operates in O(n) time by making two assumptions: elements of different types produce different trees, and developers provide
keyprops to hint which child elements are stable across renders. - You rarely interact with the Virtual DOM directly — React handles it for you.
- What is JSX?
Answer
JSX is a syntax extension for JavaScript that lets you write HTML-like markup inside JavaScript. It is not valid JavaScript on its own — it must be transpiled by a tool like Babel or the TypeScript compiler before the browser can run it.
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}Under the hood, JSX is transformed into React.createElement() calls (or the newer automatic JSX transform).
- JSX is optional — you can write React without it — but it is used in virtually all React projects because it is more readable and declarative.
- JSX expressions can embed any valid JavaScript expression inside curly braces
{}. - Since JSX is closer to JavaScript than HTML, it uses camelCase for attribute names (e.g.,
classNameinstead ofclass,onClickinstead ofonclick).
- What is the difference between state and props?
Answer
Props (short for "properties") are values passed into a component by its parent. They are read-only — a component cannot modify its own props.
State is data managed within a component. It is created and updated by the component itself (using useState or useReducer), and when state changes, the component re-renders.
function Counter({ label }) {
// `label` is a prop — passed in from the parent
// `count` is state — managed locally
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
{label}: {count}
</button>
);
}- Props flow down (parent to child). State is local to the component.
- State can be passed as props to child components.
- When either props or state change, React re-renders the component.
More reading: React docs — State: A Component's Memory
- What are React Hooks? Name some common ones.
Answer
Hooks are functions that let you use React features (state, side effects, context, etc.) inside functional components. They were introduced in React 16.8 and are now the standard way to write React components.
| Hook | Purpose |
|---|---|
useState |
Manage local state |
useEffect |
Run side effects (data fetching, subscriptions, DOM manipulation) |
useContext |
Read values from React Context |
useRef |
Hold a mutable value or reference a DOM element |
useMemo |
Memoize an expensive computation |
useCallback |
Memoize a function reference |
useReducer |
Manage complex state with a reducer pattern |
- Only call hooks at the top level of a component or custom hook — never inside loops, conditions, or nested functions.
- Only call hooks from React function components or custom hooks — never from regular JavaScript functions.
More reading: React docs — Built-in React Hooks
- Explain
useStateand how it differs from class component state.
Answer
useState is a hook that adds local state to a functional component. It returns a pair: the current state value and a function to update it.
function Toggle() {
const [isOn, setIsOn] = useState(false);
return (
<button onClick={() => setIsOn(!isOn)}>
{isOn ? "ON" : "OFF"}
</button>
);
}- Granular state: With
useState, each piece of state gets its own variable and setter, rather than a singlethis.stateobject. This makes state easier to manage and share via custom hooks. - No merging:
useStatereplaces the value entirely on update, whereasthis.setStatein classes does a shallow merge. - Functional updates: When the new state depends on the previous state, pass a function to the setter:
setCount(prev => prev + 1);More reading: React docs — useState
- What does
useEffectdo and when would you use it?
Answer
useEffect lets you run side effects in functional components. Side effects are operations that reach outside the component's rendering logic — things like data fetching, setting up subscriptions, or manually changing the DOM.
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => setUser(data));
}, [userId]); // Re-runs only when userId changes
if (!user) return <p>Loading...</p>;
return <h1>{user.name}</h1>;
}- The dependency array (second argument) controls when the effect re-runs. An empty array
[]means "run once on mount." Omitting it means "run after every render." - The effect can return a cleanup function that runs before the effect re-runs or when the component unmounts — useful for removing event listeners or cancelling subscriptions.
useEffectreplaces the class lifecycle methodscomponentDidMount,componentDidUpdate, andcomponentWillUnmount.
More reading: React docs — useEffect
- What is the purpose of "key" in React?
Answer
Keys help React identify which items in a list have changed, been added, or been removed. They give elements a stable identity across renders so React can efficiently update the DOM.
function TodoList({ todos }) {
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
}- Keys should be stable, unique, and predictable. Using the array index as a key is discouraged when the list can be reordered or filtered, because it can cause subtle bugs with component state.
- Keys only need to be unique among siblings, not globally.
- React uses keys during reconciliation to match children in the old tree with children in the new tree.
More reading: React docs — Rendering Lists
- What is the Context API and when should you use it?
Answer
The Context API lets you pass data through the component tree without manually threading props through every level (a problem known as "prop drilling").
const ThemeContext = createContext("light");
function App() {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={theme}>
<Toolbar />
</ThemeContext.Provider>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={theme}>Click me</button>;
}- Sharing "global" values like the current theme, locale, or authenticated user.
- When passing props through many intermediate components that don't use the data themselves.
- Context is not a replacement for all state management. Frequent state changes in Context can cause unnecessary re-renders of every consumer.
- For complex state logic with many actions, consider
useReducercombined with Context, or an external state management library.
More reading: React docs — Passing Data Deeply with Context
- What is one-way data flow in React?
Answer
React follows a unidirectional (one-way) data flow: data moves from parent components down to child components via props. A child component cannot directly modify the data it receives.
If a child needs to communicate back to a parent, the parent passes a callback function as a prop, and the child calls it:
function Parent() {
const [value, setValue] = useState("");
return <Child onUpdate={setValue} />;
}
function Child({ onUpdate }) {
return <input onChange={e => onUpdate(e.target.value)} />;
}- One-way data flow makes applications more predictable and easier to debug, because you can always trace where data comes from.
- This is in contrast to two-way data binding (e.g., Angular's
ngModel), where changes in the UI automatically update the model and vice versa. - For data that needs to be shared across many components, use Context or a state management library rather than passing callbacks through many layers.
- How do you start a new React project today?
Answer
The original create-react-app (CRA) tool is deprecated and no longer maintained. The React team now recommends using a framework or a modern build tool:
- Vite — A fast build tool with first-class React support. Great for single-page applications and when you don't need a full framework.
npm create vite@latest my-app -- --template react
- Next.js — A full-stack React framework with routing, server-side rendering, and static site generation built in.
- Remix — A full-stack framework focused on web standards and progressive enhancement.
- The React docs recommend starting with a framework for most production apps. See react.dev — Start a New React Project.
- Vite is the go-to choice when you want a lightweight setup without a framework.
- The choice depends on your project's needs: static site, SPA, server-rendered, etc.
- What is the purpose of "refs" in React?
Answer
Refs provide a way to access a DOM node or a value that persists across renders without triggering a re-render when it changes.
In modern React, you create refs with the useRef hook:
function TextInput() {
const inputRef = useRef(null);
function handleClick() {
inputRef.current.focus();
}
return (
<>
<input ref={inputRef} />
<button onClick={handleClick}>Focus the input</button>
</>
);
}- Focusing an input or scrolling to an element.
- Storing a mutable value (like a timer ID) that doesn't need to cause a re-render.
- Integrating with third-party DOM libraries.
More reading: React docs — Referencing Values with Refs
- What's the difference between an Element and a Component in React?
Answer
A React element is a plain object describing what you want to see on the screen. It is the return value of JSX expressions and React.createElement(). Elements are immutable — once created, you can't change their children or attributes.
A React component is a function (or, less commonly today, a class) that accepts props and returns React elements. Components are reusable and can manage their own state.
// This is a component (a function that returns elements)
function Welcome({ name }) {
return <h1>Hello, {name}</h1>;
}
// This JSX produces a React element
const element = <Welcome name="World" />;- What is a custom hook and why would you create one?
Answer
A custom hook is a JavaScript function whose name starts with use and that can call other hooks. Custom hooks let you extract and reuse stateful logic between components without changing the component hierarchy.
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 Dashboard() {
const width = useWindowWidth();
return <p>Window width: {width}px</p>;
}- Custom hooks replace older patterns like higher-order components (HOCs) and render props for sharing logic. They are simpler and more composable.
- Each component that calls a custom hook gets its own independent copy of the state — hooks don't share state between components, they share logic.
- Common examples:
useFetch,useLocalStorage,useDebounce,useMediaQuery.
More reading: React docs — Reusing Logic with Custom Hooks
- What is the difference between controlled and uncontrolled components?
Answer
A controlled component is a form element whose value is driven by React state. The component renders the current state value and updates it via an event handler — React is the "single source of truth."
function ControlledInput() {
const [value, setValue] = useState("");
return <input value={value} onChange={e => setValue(e.target.value)} />;
}An uncontrolled component lets the DOM handle the form data. You use a ref to read the value when you need it, rather than tracking every change in state.
function UncontrolledInput() {
const inputRef = useRef(null);
function handleSubmit() {
alert(inputRef.current.value);
}
return (
<>
<input ref={inputRef} defaultValue="" />
<button onClick={handleSubmit}>Submit</button>
</>
);
}- Controlled components are recommended for most cases because they make it easy to validate, transform, or conditionally disable inputs.
- Uncontrolled components can be simpler for basic forms or when integrating with non-React code.
- What is
React.memoand when should you use it?
Answer
React.memo is a higher-order component that memoizes a functional component. If the component's props haven't changed (shallow comparison), React skips re-rendering it and reuses the last rendered result.
const ExpensiveList = React.memo(function ExpensiveList({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
});- Components that render often with the same props (e.g., a list item in a large list where only some items change).
- Components with expensive rendering logic.
- Don't wrap every component in
React.memoby default. Memoization itself has a cost (comparing props), and for simple components the overhead can outweigh the benefit. - If the component's props change on nearly every render (e.g., a new object or function is created each time),
React.memowon't help unless you also memoize those props withuseMemooruseCallback.
More reading: React docs — memo