🚀 Advanced React Interview Questions

25 Fresh, Important Questions to Master Your React Interview

1

What is the difference between React.memo and PureComponent?

📝 Explanation

React.memo is used for functional components to prevent re-renders if props are unchanged, while PureComponent is for class components and performs a shallow comparison of props and state. Knowing the difference shows your understanding of React's rendering optimization.

💻 Code Example

// React.memo for functional component
const MyComponent = React.memo(({ value }) => {
  console.log('Rendering');
  return <div>{value}</div>;
});

// PureComponent for class component
class MyPureComponent extends React.PureComponent {
  render() {
    console.log('Rendering');
    return <div>{this.props.value}</div>;
  }
}

🎯 Interview Relevance

Shows your ability to optimize rendering in both functional and class components.

2

How do you handle multiple useEffect calls in a single component?

📝 Explanation

Multiple useEffect calls can be used to separate concerns (e.g., one for data fetching, another for event listeners). Ensure proper cleanup in each to avoid memory leaks. This question tests your ability to organize side effects.

💻 Code Example

import { useEffect, useState } from 'react';
function Component() {
  const [data, setData] = useState(null);
  const [width, setWidth] = useState(window.innerWidth);

  // Effect for fetching data
  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(res => res.json())
      .then(setData);
  }, []);

  // Effect for window resize
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return <div>{data ? data.name : 'Loading...'} | Width: {width}</div>;
}

🎯 Interview Relevance

Demonstrates clean code organization and proper cleanup of side effects.

3

What is the useReducer hook, and when is it preferred over useState?

📝 Explanation

useReducer manages complex state logic with a reducer function, ideal when state transitions depend on actions or involve multiple sub-values. It's preferred over useState for complex state updates, like form handling or game logic.

💻 Code Example

import { useReducer } from 'react';
const initialState = { count: 0, step: 1 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment': 
      return { ...state, count: state.count + state.step };
    case 'setStep': 
      return { ...state, step: action.payload };
    default: 
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <p>Count: {state.count}</p>
      <input
        type="number"
        value={state.step}
        onChange={(e) => dispatch({ 
          type: 'setStep', 
          payload: Number(e.target.value) 
        })}
      />
      <button onClick={() => dispatch({ type: 'increment' })}>
        Add
      </button>
    </div>
  );
}

🎯 Interview Relevance

Shows your ability to handle complex state logic, a common requirement in real-world apps.

4

How do you implement a custom hook for debouncing an input?

📝 Explanation

Debouncing delays function execution to optimize performance (e.g., for search inputs). A custom hook for debouncing shows your ability to encapsulate reusable logic.

💻 Code Example

import { useState, useEffect } from 'react';

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);
  
  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);
  
  return debouncedValue;
}

function SearchInput() {
  const [input, setInput] = useState('');
  const debouncedInput = useDebounce(input, 500);
  
  useEffect(() => {
    console.log('Search for:', debouncedInput);
  }, [debouncedInput]);
  
  return (
    <input 
      value={input} 
      onChange={(e) => setInput(e.target.value)} 
    />
  );
}

🎯 Interview Relevance

Tests your ability to create reusable hooks and optimize user input handling.

5

How do you handle accessibility (a11y) in React apps?

📝 Explanation

Accessibility ensures apps are usable by people with disabilities. Use semantic HTML, ARIA attributes, and focus management. This is critical for real-world apps and shows awareness of inclusive design.

💻 Code Example

function AccessibleForm() {
  return (
    <form aria-labelledby="form-title">
      <h2 id="form-title">Login Form</h2>
      <label htmlFor="username">Username</label>
      <input id="username" aria-required="true" />
      <button type="submit" aria-label="Submit form">
        Submit
      </button>
    </form>
  );
}

🎯 Interview Relevance

Highlights your understanding of web standards and user inclusivity.

6

What is the significance of the dependency array in useEffect?

📝 Explanation

The dependency array in useEffect controls when the effect runs. If empty ([]), it runs once on mount. If it includes variables, the effect runs when those variables change. Missing dependencies can cause bugs.

💻 Code Example

import { useEffect, useState } from 'react';

function Example({ id }) {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetch(`https://api.example.com/data/${id}`)
      .then(res => res.json())
      .then(setData);
  }, [id]); // Runs when `id` changes
  
  return <div>{data ? data.name : 'Loading...'}</div>;
}

🎯 Interview Relevance

Tests your understanding of how to control side effects and avoid common bugs.

7

How do you handle dynamic forms with multiple inputs in React?

📝 Explanation

Dynamic forms involve managing an array of inputs in state, often using map to render inputs and updating state based on input names or indices. This tests your ability to manage complex form state.

💻 Code Example

import { useState } from 'react';

function DynamicForm() {
  const [inputs, setInputs] = useState([{ id: 1, value: '' }]);
  
  const addInput = () => setInputs([
    ...inputs, 
    { id: inputs.length + 1, value: '' }
  ]);
  
  const handleChange = (id, value) => {
    setInputs(inputs.map(input => 
      input.id === id ? { ...input, value } : input
    ));
  };
  
  return (
    <div>
      {inputs.map(input => (
        <input
          key={input.id}
          value={input.value}
          onChange={(e) => handleChange(input.id, e.target.value)}
        />
      ))}
      <button onClick={addInput}>Add Input</button>
    </div>
  );
}

🎯 Interview Relevance

Common in real-world apps like surveys or multi-field forms.

8

What is the useImperativeHandle hook, and when is it used?

📝 Explanation

useImperativeHandle customizes the instance value exposed by a ref when using forwardRef. It's used in rare cases when a parent component needs to control a child component's methods.

💻 Code Example

import { useRef, useImperativeHandle, forwardRef } from 'react';

const Child = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    focus: () => console.log('Child focused'),
  }));
  
  return <div>Child Component</div>;
});

function Parent() {
  const childRef = useRef();
  
  return (
    <div>
      <Child ref={childRef} />
      <button onClick={() => childRef.current.focus()}>
        Focus Child
      </button>
    </div>
  );
}

🎯 Interview Relevance

Tests advanced knowledge of ref handling and component communication.

9

How do you optimize a large list rendering in React?

📝 Explanation

For large lists, use virtualization (e.g., react-window or react-virtualized) to render only visible items, reducing DOM load. Also, ensure unique key props and memoize components.

💻 Code Example

import { FixedSizeList } from 'react-window';

function LargeList({ items }) {
  const Row = ({ index, style }) => (
    <div style={style}>{items[index]}</div>
  );
  
  return (
    <FixedSizeList 
      height={400} 
      width={300} 
      itemCount={items.length} 
      itemSize={35}
    >
      {Row}
    </FixedSizeList>
  );
}

🎯 Interview Relevance

Shows your ability to handle performance issues in data-heavy apps.

10

How do you handle real-time updates in a React app (e.g., WebSocket)?

📝 Explanation

Use WebSockets or libraries like socket.io with useEffect to listen for real-time updates and update state. Cleanup the connection on unmount to avoid leaks.

💻 Code Example

import { useState, useEffect } from 'react';
import io from 'socket.io-client';

function RealTimeChat() {
  const [messages, setMessages] = useState([]);
  
  useEffect(() => {
    const socket = io('https://example.com');
    
    socket.on('message', (message) => {
      setMessages((prev) => [...prev, message]);
    });
    
    return () => socket.disconnect();
  }, []);
  
  return (
    <div>
      {messages.map((msg, i) => (
        <p key={i}>{msg}</p>
      ))}
    </div>
  );
}

🎯 Interview Relevance

Tests your ability to integrate real-time features, common in chat or dashboard apps.

11

What is code splitting in React, and why is it important?

📝 Explanation

Code splitting divides your app's JavaScript bundle into smaller chunks, loading only what's needed. It improves initial load time. React supports this with React.lazy and Suspense.

💻 Code Example

import { lazy, Suspense } from 'react';

const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}

🎯 Interview Relevance

Shows knowledge of performance optimization for large apps.

12

How do you handle file uploads in a React app?

📝 Explanation

Use an <input type="file"> and the FormData API to handle file uploads. Manage the file in state and send it to a server via an API call.

💻 Code Example

import { useState } from 'react';

function FileUpload() {
  const [file, setFile] = useState(null);
  
  const handleUpload = async () => {
    const formData = new FormData();
    formData.append('file', file);
    await fetch('/upload', { 
      method: 'POST', 
      body: formData 
    });
  };
  
  return (
    <div>
      <input 
        type="file" 
        onChange={(e) => setFile(e.target.files[0])} 
      />
      <button onClick={handleUpload}>Upload</button>
    </div>
  );
}

🎯 Interview Relevance

Common in apps requiring user uploads, like profile pictures or documents.

🎓 Why These Questions Are Important

💡 Interview Preparation Tips

  1. Practice coding: Build small projects (e.g., a table, modal, or infinite scroll) to solidify these concepts.
  2. Explain your code: Be ready to walk through your code and justify your approach (e.g., why you used useReducer vs. useState).
  3. Know trade-offs: Understand when to use certain hooks, libraries, or patterns (e.g., Context vs. Redux).
  4. Mock interviews: Simulate coding interviews with platforms like LeetCode, CodePen, or Pramp.
  5. Stay updated: Be familiar with React 18 features like useTransition and concurrent rendering.