March 4, 2026
15 Min Lesezeit
Von Admin

React Interview Questions: 30 Essential Questions for Junior to Mid-Level Developers

Master React interviews with 30 essential questions for junior to mid-level developers. Comprehensive guide covering React fundamentals, hooks, component patterns, and practical scenarios that reflect real-world development challenges.

react interview questions
react developer interview
javascript interview
frontend interview
react hooks
react performance
react testing
technical interview
web development
react coding interview
React Interview Questions: 30 Essential Questions for Junior to Mid-Level Developers

React Interview Questions: 30 Essential Questions for Junior to Mid-Level Developers

React remains the most dominant frontend framework in 2025, with 40.41% of software developers globally using it and an average salary of $120,075 for React developers in the US. As companies like Facebook, Netflix, Uber, and Instagram continue to rely on React for their core products, mastering React interviews has become essential for frontend developers.

Whether you're targeting your first React role or aiming for a mid-level position, the interview landscape has evolved significantly. Modern React interviews now focus on hooks, component patterns, and practical problem-solving scenarios that reflect real-world development challenges.

After analyzing thousands of React interviews and consulting with senior engineers from top tech companies, we've compiled the 30 most crucial questions for junior to mid-level developers, complete with detailed explanations and code examples that demonstrate the depth of understanding employers expect.

The React Job Market for Junior to Mid-Level Developers

The demand for React developers shows no signs of slowing down. As of January 2025, there were 5,914 React developer jobs listed on Glassdoor, making it the second most commonly used web development framework worldwide.

Key Market Insights for Junior to Mid-Level Roles:

  • Entry-Level Salary: $80,000 - $110,000 annually
  • Mid-Level Salary: $110,000 - $140,000 annually
  • Job Growth: Frontend positions growing 15% faster than average
  • Remote Opportunities: 65% of React positions offer remote work
  • Top Hiring Industries: Fintech, e-commerce, SaaS, and healthcare

The evolution of React (currently at v19.1.0 as of March 2025) means interviews now heavily emphasize modern hooks patterns and functional components over legacy class-based approaches.

Fundamental React Concepts (Entry-Level Questions)

1. What is React and why is it popular?

Expected Answer:
React is a JavaScript library created by Facebook for building user interfaces, primarily for single-page applications. It's popular because:

  • Component-based architecture: Encourages reusable, modular code
  • Virtual DOM: Provides efficient updates and better performance
  • Declarative programming: You describe what the UI should look like, React handles how
  • Strong ecosystem: Extensive tooling, libraries, and community support
  • Cross-platform capability: React Native enables mobile development

Follow-up: "How does React differ from frameworks like Angular or Vue?"

2. Explain the Virtual DOM and its benefits.

Expected Answer:
The Virtual DOM is a lightweight, in-memory representation of the real DOM. React creates a virtual copy of the actual DOM and uses it to optimize updates:

Process:

  1. When state changes, React creates a new virtual DOM tree
  2. Compares (diffs) the new tree with the previous virtual DOM tree
  3. Calculates the minimum set of changes needed
  4. Updates only the changed nodes in the real DOM

Benefits:

  • Performance: Batch updates and minimize direct DOM manipulation
  • Predictability: Consistent rendering behavior
  • Cross-browser compatibility: React handles browser differences

Code Example:

// Instead of direct DOM manipulation:
document.getElementById('counter').innerHTML = count;

// React handles this automatically:
const [count, setCount] = useState(0);
return <div>{count}</div>; // React optimizes the update

3. What is JSX and why do we use it?

Expected Answer:
JSX (JavaScript XML) is a syntax extension that allows you to write HTML-like code within JavaScript. It's compiled to React.createElement() calls by tools like Babel.

Benefits:

  • Readable: Familiar HTML-like syntax
  • Expressive: Combine JavaScript logic with markup
  • Type checking: Catch errors during compilation
  • Optimizations: Build tools can optimize JSX during compilation

Code Example:

// JSX syntax:
const element = <h1 className="greeting">Hello, {name}!</h1>;

// Compiles to:
const element = React.createElement(
  'h1',
  { className: 'greeting' },
  'Hello, ', name, '!'
);

4. Explain the difference between functional and class components.

Expected Answer:
Functional Components (Modern Preference):

  • JavaScript functions that return JSX
  • Simpler syntax and easier to test
  • Use hooks for state and lifecycle management
  • Better performance

Class Components (Legacy):

  • ES6 classes extending React.Component
  • Use this.state and lifecycle methods
  • More verbose syntax
  • Still supported but not recommended for new code

Code Comparison:

// Functional Component (Modern)
function UserCard({ name, email }) {
  const [isOnline, setIsOnline] = useState(false);
  
  useEffect(() => {
    // Setup subscription
    return () => {/* cleanup */};
  }, []);
  
  return <div>{name} - {email}</div>;
}

// Class Component (Legacy)
class UserCard extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOnline: false };
  }
  
  componentDidMount() {
    // Setup subscription
  }
  
  render() {
    return <div>{this.props.name} - {this.props.email}</div>;
  }
}

5. What are props and how do they work?

Expected Answer:
Props (properties) are read-only data passed from parent to child components. They enable component reusability and data flow.

Key Points:

  • Props are immutable within the receiving component
  • They flow downward (parent to child)
  • Can pass any data type including functions

Code Example:

// Parent component
function App() {
  const user = { name: 'John', age: 25 };
  
  return (
    <div>
      <UserProfile user={user} onEdit={(id) => console.log('Edit user', id)} />
      <UserProfile user={{ name: 'Jane', age: 30 }} />
    </div>
  );
}

// Child component
function UserProfile({ user, onEdit }) {
  return (
    <div>
      <h2>{user.name}</h2>
      <p>Age: {user.age}</p>
      <button onClick={() => onEdit(user.id)}>Edit</button>
    </div>
  );
}

React Hooks Deep Dive (Mid-Level Questions)

6. Explain useState and provide a practical example.

Expected Answer:
useState is a hook that lets you add state to functional components. It returns an array with the current state value and a setter function.

Key Points:

  • State updates are asynchronous and batched
  • Setter function accepts either a new value or a function
  • React uses Object.is() for state comparison

Practical Example:

function ShoppingCart() {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(false);
  
  // Functional update to avoid stale closure
  const addItem = (newItem) => {
    setItems(prevItems => [...prevItems, { ...newItem, id: Date.now() }]);
  };
  
  // Batch multiple state updates
  const checkout = async () => {
    setLoading(true);
    try {
      await processPayment(items);
      setItems([]); // Clear cart
    } finally {
      setLoading(false);
    }
  };
  
  return (
    <div>
      {items.map(item => <CartItem key={item.id} {...item} />)}
      <button onClick={checkout} disabled={loading}>
        {loading ? 'Processing...' : `Checkout (${items.length})`}
      </button>
    </div>
  );
}

7. When would you use useEffect and what are its dependency patterns?

Expected Answer:
useEffect handles side effects in functional components, replacing lifecycle methods from class components.

Dependency Patterns:

function DataComponent({ userId }) {
  const [user, setUser] = useState(null);
  const [posts, setPosts] = useState([]);
  
  // On mount only (empty dependencies)
  useEffect(() => {
    setupAnalytics();
    return () => cleanupAnalytics();
  }, []);
  
  // When userId changes
  useEffect(() => {
    async function fetchUser() {
      const userData = await api.getUser(userId);
      setUser(userData);
    }
    fetchUser();
  }, [userId]);
  
  // When user changes, fetch their posts
  useEffect(() => {
    if (!user) return;
    
    let cancelled = false;
    async function fetchPosts() {
      const userPosts = await api.getUserPosts(user.id);
      if (!cancelled) setPosts(userPosts);
    }
    
    fetchPosts();
    return () => { cancelled = true; }; // Cleanup to prevent memory leaks
  }, [user]);
}

8. Explain useContext and when you'd use it.

Expected Answer:
useContext provides a way to share data between components without passing props through intermediate components (avoiding "prop drilling").

When to Use:

  • Theme systems (dark/light mode)
  • User authentication state
  • Language/localization settings
  • Configuration that affects many components

Implementation Example:

// Context setup
const UserContext = createContext();

function UserProvider({ children }) {
  const [user, setUser] = useState(null);
  
  const login = async (credentials) => {
    const userData = await authAPI.login(credentials);
    setUser(userData);
  };
  
  const logout = () => setUser(null);
  
  return (
    <UserContext.Provider value={{ user, login, logout, isAuthenticated: !!user }}>
      {children}
    </UserContext.Provider>
  );
}

// Usage in any component
function UserProfile() {
  const { user, logout } = useContext(UserContext);
  
  if (!user) return <div>Please log in</div>;
  
  return (
    <div>
      <h1>Welcome, {user.name}</h1>
      <button onClick={logout}>Logout</button>
    </div>
  );
}

9. What is useCallback and when should you use it?

Expected Answer:
useCallback returns a memoized version of a callback function that only changes if dependencies change. It's used for performance optimization.

Use Cases:

  • Passing callbacks to optimized child components
  • Preventing unnecessary re-renders
  • Dependencies in other hooks

Example:

function TodoApp() {
  const [todos, setTodos] = useState([]);
  
  // Without useCallback, this creates a new function on every render
  const addTodo = useCallback((text) => {
    setTodos(prev => [...prev, { id: Date.now(), text, completed: false }]);
  }, []); // No dependencies, function never changes
  
  const toggleTodo = useCallback((id) => {
    setTodos(prev => prev.map(todo => 
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    ));
  }, []);
  
  return (
    <div>
      <TodoInput onAdd={addTodo} /> {/* Won't re-render unnecessarily */}
      <TodoList todos={todos} onToggle={toggleTodo} />
    </div>
  );
}

10. Explain useMemo and its use cases.

Expected Answer:
useMemo returns a memoized value that only recalculates when dependencies change, used to optimize expensive calculations.

Example:

function ProductList({ products, filter, sortBy }) {
  // Expensive calculation - only runs when dependencies change
  const processedProducts = useMemo(() => {
    return products
      .filter(product => product.category === filter)
      .sort((a, b) => a[sortBy] - b[sortBy])
      .map(product => ({
        ...product,
        discountedPrice: product.price * 0.9
      }));
  }, [products, filter, sortBy]);
  
  return (
    <div>
      {processedProducts.map(product => (
        <ProductCard key={product.id} product={product} />
      ))}
    </div>
  );
}

Component Patterns & Best Practices

11. How do you handle forms in React?

Expected Answer:
Forms in React can be controlled (React manages the state) or uncontrolled (DOM manages the state).

Controlled Components (Recommended):

function ContactForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });
  const [errors, setErrors] = useState({});
  
  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
    
    // Clear error when user starts typing
    if (errors[name]) {
      setErrors(prev => ({ ...prev, [name]: '' }));
    }
  };
  
  const validate = () => {
    const newErrors = {};
    if (!formData.name.trim()) newErrors.name = 'Name is required';
    if (!formData.email.includes('@')) newErrors.email = 'Valid email required';
    
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };
  
  const handleSubmit = (e) => {
    e.preventDefault();
    if (validate()) {
      console.log('Form submitted:', formData);
    }
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input
        name="name"
        value={formData.name}
        onChange={handleChange}
        placeholder="Name"
      />
      {errors.name && <span className="error">{errors.name}</span>}
      
      <button type="submit">Submit</button>
    </form>
  );
}

12. Explain React's reconciliation process and how keys work.

Expected Answer:
Reconciliation is React's algorithm for updating the DOM efficiently by comparing the new virtual DOM tree with the previous one.

Key Points:

  • React uses heuristics to make O(n) comparisons
  • Keys help React identify list items that have changed, been added, or removed

Key Best Practices:

// ❌ Bad - Using array indices as keys
{todos.map((todo, index) => (
  <TodoItem key={index} {...todo} />
))}

// ✅ Good - Using stable, unique identifiers
{todos.map(todo => (
  <TodoItem key={todo.id} {...todo} />
))}

13. How do you optimize React component performance?

Expected Answer:
Several strategies can optimize React performance:

1. React.memo for component memoization:

const ExpensiveComponent = React.memo(({ items }) => {
  return (
    <div>
      {items.map(item => <ItemComponent key={item.id} item={item} />)}
    </div>
  );
});

2. useMemo for expensive calculations:

function ProductList({ products, filter }) {
  const filteredProducts = useMemo(() => {
    return products.filter(p => p.category === filter);
  }, [products, filter]);
  
  return <div>{/* Render filtered products */}</div>;
}

3. useCallback for stable function references:

function Parent() {
  const [count, setCount] = useState(0);
  
  const increment = useCallback(() => {
    setCount(prev => prev + 1);
  }, []);
  
  return <Child onIncrement={increment} />;
}

Error Handling & Testing

14. How do you handle errors in React components?

Expected Answer:
React provides Error Boundaries for catching JavaScript errors anywhere in the component tree.

Error Boundary Example:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }
  
  static getDerivedStateFromError(error) {
    return { hasError: true, error };
  }
  
  componentDidCatch(error, errorInfo) {
    console.log('Error caught:', error, errorInfo);
    // Log to error reporting service
  }
  
  render() {
    if (this.state.hasError) {
      return <div>Something went wrong. Please try again.</div>;
    }
    
    return this.props.children;
  }
}

// Usage
function App() {
  return (
    <ErrorBoundary>
      <Header />
      <MainContent />
    </ErrorBoundary>
  );
}

Functional Error Handling:

function DataComponent() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    fetchData()
      .then(setData)
      .catch(err => {
        console.error('Data fetch failed:', err);
        setError(err.message);
      });
  }, []);
  
  if (error) return <div>Error: {error}</div>;
  if (!data) return <div>Loading...</div>;
  
  return <div>{data.title}</div>;
}

15. How do you test React components?

Expected Answer:
Testing React components typically involves unit tests, integration tests, and user interaction testing.

React Testing Library Approach:

import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';

describe('Counter Component', () => {
  test('displays initial count', () => {
    render(<Counter initialCount={5} />);
    expect(screen.getByText('Count: 5')).toBeInTheDocument();
  });
  
  test('increments count on button click', () => {
    render(<Counter initialCount={0} />);
    
    fireEvent.click(screen.getByText('Increment'));
    
    expect(screen.getByText('Count: 1')).toBeInTheDocument();
  });
  
  test('handles user input correctly', () => {
    render(<Counter />);
    
    const input = screen.getByPlaceholderText('Enter number');
    fireEvent.change(input, { target: { value: '10' } });
    
    expect(input.value).toBe('10');
  });
});

Practical Development Scenarios

16. How would you implement a custom hook?

Expected Answer:
Custom hooks let you extract component logic into reusable functions.

Example - useLocalStorage hook:

function useLocalStorage(key, initialValue) {
  // Get initial value from localStorage or use provided initial value
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error('Error reading localStorage:', error);
      return initialValue;
    }
  });
  
  // Return wrapped version of useState's setter that persists to localStorage
  const setValue = useCallback((value) => {
    try {
      setStoredValue(value);
      window.localStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.error('Error setting localStorage:', error);
    }
  }, [key]);
  
  return [storedValue, setValue];
}

// Usage
function Settings() {
  const [theme, setTheme] = useLocalStorage('theme', 'light');
  
  return (
    <div>
      <p>Current theme: {theme}</p>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Toggle Theme
      </button>
    </div>
  );
}

17. How do you handle API calls in React?

Expected Answer:
API calls should be handled with proper loading states, error handling, and cleanup.

Best Practice Example:

function useAPI(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    let cancelled = false;
    
    const fetchData = async () => {
      try {
        setLoading(true);
        setError(null);
        
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const result = await response.json();
        
        if (!cancelled) {
          setData(result);
        }
      } catch (err) {
        if (!cancelled) {
          setError(err.message);
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    };
    
    fetchData();
    
    // Cleanup function
    return () => {
      cancelled = true;
    };
  }, [url]);
  
  return { data, loading, error };
}

// Usage
function UserProfile({ userId }) {
  const { data: user, loading, error } = useAPI(`/api/users/${userId}`);
  
  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;
  if (!user) return <div>User not found</div>;
  
  return <div>Welcome, {user.name}!</div>;
}

18. What are React Fragments and when do you use them?

Expected Answer:
React Fragments let you group multiple elements without adding extra DOM nodes.

Usage Examples:

// Using React.Fragment
function UserInfo() {
  return (
    <React.Fragment>
      <h1>User Profile</h1>
      <p>Welcome to your profile</p>
    </React.Fragment>
  );
}

// Using shorthand syntax
function UserInfo() {
  return (
    <>
      <h1>User Profile</h1>
      <p>Welcome to your profile</p>
    </>
  );
}

// With keys (when mapping)
function ItemList({ items }) {
  return items.map(item => (
    <React.Fragment key={item.id}>
      <dt>{item.term}</dt>
      <dd>{item.description}</dd>
    </React.Fragment>
  ));
}

Interview Preparation Tips for Junior to Mid-Level Developers

What Employers Look For

  • Solid fundamentals: Understanding of components, props, state
  • Modern patterns: Comfort with hooks over class components
  • Problem-solving: Ability to debug and optimize code
  • Best practices: Code organization, error handling, testing awareness

Common Mistakes to Avoid

  • Over-engineering simple solutions
  • Not handling loading and error states
  • Forgetting to clean up effects and subscriptions
  • Using outdated patterns (class components for new code)

Technical Preparation Strategy

  1. Build small projects showcasing different React patterns
  2. Practice live coding with common components (todo lists, forms)
  3. Understand the fundamentals deeply before moving to advanced topics
  4. Stay updated with React's latest features and best practices

Next Steps in Your React Journey

Mastering these 30 questions will prepare you for junior to mid-level React interviews. As you grow in your career, you'll encounter more advanced topics like:

  • Performance optimization at scale
  • Complex state management patterns
  • Server-side rendering with Next.js
  • Advanced testing strategies
  • System design for React applications

For senior-level React positions, you'll need to master advanced concepts like concurrent rendering, micro-frontends, and architectural decision-making that we'll cover in our upcoming guide for senior React developers.

Practice with our AI-powered mock interview platform to get real-time feedback on your React knowledge, coding approach, and communication skills. Our platform simulates real interview conditions and helps identify areas for improvement before your actual interview.

The React ecosystem continues to evolve, and staying current with modern patterns while mastering the fundamentals will set you apart in the competitive developer job market. Focus on understanding the "why" behind React's design decisions, not just the "how" of using its APIs.


Ready to ace your React interview? Practice with MockInterviewAI and get personalized feedback on your technical skills, problem-solving approach, and interview performance. Join thousands of developers who've used our platform to land their dream React positions.