Interview Prep/React

Top 50 React Interview Questions & Answers 2025

Prepare for your React interview with 50+ real questions asked at top tech companies. From hooks to performance optimization.

20 Questions~30 min read7 CategoriesUpdated 2025
Practice React Quiz

Core Concepts

01 · 4q

The Virtual DOM is a lightweight JavaScript representation of the actual DOM. React uses it to optimize rendering by comparing the virtual DOM with the previous version (diffing), then only updating the parts of the real DOM that changed (reconciliation). This process is much faster than directly manipulating the DOM.

React's reconciliation compares the new virtual DOM with the previous one to determine minimal DOM updates. Key principles: (1) Different element types produce different trees, (2) Keys help identify which items changed in lists, (3) React compares props and updates when they change. The algorithm is O(n) complexity by assuming these heuristics, making updates efficient.

ReactDOM.createPortal(child, container) renders a component outside its parent DOM hierarchy, while keeping it in the React tree (events bubble normally). Use for: modals, tooltips, dropdowns that need to escape overflow:hidden or z-index stacking contexts. The portal's child still receives context from its React parent and events bubble up through the React tree.

Fiber is React's reconciliation engine (rewritten in React 16). Key capabilities: incremental rendering (split work into chunks), pause/abort/resume work, assign priority to updates, return multiple elements (fragments). Fiber is the data structure (linked list of units of work). This architecture enabled concurrent mode, Suspense, and error boundaries.

Hooks

02 · 4q

useState is ideal for simple state with primitive values or when state updates are independent. useReducer is better for complex state logic with multiple sub-values, when the next state depends on the previous one, or when you want to centralize state update logic. useReducer also makes it easier to test state transitions and is preferred when state logic becomes complex.

Use the useEffect hook to handle side effects like data fetching, subscriptions, or DOM manipulation. The hook takes a callback function and an optional dependency array. Effects run after render, and you can return a cleanup function. For data fetching, consider using libraries like React Query or SWR for better caching and state management.

useEffect runs asynchronously after the browser has painted — ideal for data fetching, subscriptions, event listeners. useLayoutEffect runs synchronously after DOM mutations but before the browser paints — use for reading DOM layout (element dimensions) or avoiding visual flicker. Prefer useEffect; only reach for useLayoutEffect when you see flickering or need synchronous DOM measurements.

Rules: (1) Only call Hooks at the top level — not inside loops, conditions, or nested functions. (2) Only call Hooks from React function components or custom Hooks — not regular JS functions. These rules exist because React relies on the order of Hook calls to correctly associate state with each Hook across re-renders. The eslint-plugin-react-hooks enforces these rules.

Performance

03 · 3q

React.memo() is a higher-order component that memoizes functional components, preventing unnecessary re-renders when props haven't changed. Use it when: (1) your component renders the same output for the same props, (2) the component re-renders frequently with the same props, (3) the component is computationally expensive. Avoid overusing it as the comparison itself has a cost.

useCallback memoizes a function reference, useful when passing callbacks to optimized child components that rely on reference equality. useMemo memoizes a computed value, useful for expensive calculations. Use useCallback when passing functions as props to prevent child re-renders. Use useMemo when computing derived data that's expensive to calculate.

Key optimization strategies: (1) Use React.memo, useMemo, useCallback to prevent unnecessary re-renders, (2) Implement code splitting with React.lazy and Suspense, (3) Virtualize long lists with react-window or react-virtualized, (4) Optimize images and use lazy loading, (5) Use production builds, (6) Profile with React DevTools, (7) Avoid inline object/function creation in render, (8) Use proper key props in lists.

Architecture

04 · 4q

React Server Components (RSC) render on the server and send HTML to the client, reducing JavaScript bundle size. They can directly access backend resources. Client Components are the traditional React components that run in the browser and handle interactivity. Use Server Components for static content and data fetching; use Client Components for interactivity, browser APIs, and state management.

Suspense lets components "wait" for something before rendering, showing a fallback in the meantime. Used with React.lazy for code splitting (lazy-loaded components), and with data-fetching libraries that implement the Suspense protocol (React Query, Relay). In React 18, Suspense works on the server too. Nest multiple Suspense boundaries for granular loading states.

Error boundaries are class components implementing componentDidCatch and/or getDerivedStateFromError. They catch errors in child component trees, log them, and render fallback UI. Function components cannot be error boundaries (yet). Wrap route-level components and third-party widgets. Libraries like react-error-boundary provide a cleaner functional wrapper API.

React 18 makes rendering interruptible — React can pause work to handle higher-priority updates (user input), then resume. Key APIs: createRoot (enables concurrent features), startTransition (mark state update as non-urgent), useDeferredValue (defer expensive re-renders), useTransition (pending state during transition). This makes UIs more responsive without manual debouncing.

State Management

05 · 2q

Context API provides a way to pass data through the component tree without prop drilling. Use Context for: theme data, user authentication, locale preferences. Use Redux when you need: predictable state updates, time-travel debugging, middleware for async logic, or complex state shared across many components. Context causes all consumers to re-render on any change; Redux allows selective subscriptions.

Prop drilling is passing props through multiple component layers just to reach a deeply nested component. Avoid with: Context API (global state accessible anywhere), state management libraries (Zustand, Redux), component composition (render children directly to avoid intermediate components), or custom hooks. Context is not a silver bullet — it causes all consumers to re-render on change.

Forms

06 · 2q

Controlled components have their form data handled by React state - the component's state is the "single source of truth." Uncontrolled components store form data in the DOM itself, accessed via refs. Controlled components offer more control and validation capabilities but require more code. Uncontrolled components are simpler for basic forms or when integrating with non-React code.

Options: controlled components (state for each field, verbose but explicit), uncontrolled (refs, less re-renders), form libraries. React Hook Form is the most performant — uncontrolled by default, minimal re-renders, built-in validation. Formik is more opinionated with Yup integration. Use Zod with React Hook Form for type-safe validation. For simple forms, built-in HTML validation often suffices.

Patterns

07 · 1q

Compound components share implicit state through context (like <Select> + <Select.Option>). Parent manages state; children access it via context. Render props pass a function as a prop, giving consumers control over rendering. Both patterns enable flexible, reusable components. Modern alternative: custom hooks extract logic while letting consumers own the rendering.

Ready to test your React skills?

Practice with interactive quizzes and get instant feedback.

Start Free Practice