Prepare for your React interview with 50+ real questions asked at top tech companies. From hooks to performance optimization.
10 Questions
~30 min read
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.
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.
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.
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.
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.
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.