Skip to main content

React JS Interview Questions and Answers

Prepare for your next React JS interview with these frequently asked questions and detailed answers covering hooks, components, state management, props, lifecycle methods, and more.

React, or ReactJS is an open-source front-end development library based on JavaScript. Facebook developed it, and it is now maintained by Meta Inc. and a vibrant community of developers. React uses a component-based architecture that consists of reusable, self-contained units called components, making the development of UI elements easy and efficient for developers.

Being one of the most popular front-end development libraries, React is a must-have skill in a front-end developer's arsenal. Below are some React interview questions and answers that can help you learn more about this front-end technology and prepare to face any interview for ReactJS.

React JS Basics

1. What is React JS? How does it differ from Angular JS? Beginner

React is a front-end and open-source JavaScript library that is useful for developing user interfaces, especially for applications with a single page. It helps build complex and reusable user interface components of mobile and web applications as it follows the component-based approach.

The important features of React are:

  • It supports server-side rendering
  • It will use the virtual DOM rather than the real DOM (Data Object Model) as RealDOM manipulations are expensive.
  • It follows unidirectional data binding or data flow.
  • It uses reusable or composable UI components for developing the view.

Example - A simple React component:

import React from 'react';

function App() {
  return (
    <div>
      <h1>Hello, React!</h1>
      <p>This is a React component.</p>
    </div>
  );
}

export default App;
Hello, React! This is a React component.

While AngularJS is a popular open-source framework that simplifies web development by creating interactive single-page applications.

Key Takeaway

React is a library (not a framework) focused solely on building UI. It uses a component-based architecture and Virtual DOM for efficient rendering.

Common Mistakes

  • Confusing React with a full framework (it only handles the View layer)
  • Saying React is the same as React Native (React Native is for mobile apps)
  • Forgetting to mention Virtual DOM when explaining React benefits

Interview Tip

Most interviewers follow up with: Virtual DOM, JSX, and Component lifecycle. Be ready to explain how React differs from Angular (library vs framework, one-way vs two-way binding).

2. What are the benefits of using JSX in React JS? Beginner

Faster Development: JSX makes it faster to build and prototype components.

Better Performance: JSX helps avoid unnecessary DOM Updates, which can lead to improved performance in React JS Applications.

Improved code readability: JSX helps write code that is easier to understand, especially when working with nested components.

Example - JSX vs without JSX:

// With JSX
const element = <h1>Hello, World!</h1>;

// Without JSX (using React.createElement)
const element = React.createElement('h1', null, 'Hello, World!');
Both produce the same output: Hello, World!

3. How to create components in React? Beginner

Components are the building blocks of creating User Interfaces (UI) in React. There are two possible ways to create a component.

Function Components: This is the simplest way to create a component:

function Greeting({ message }) {
  return <h1>{`Hello, ${message}`}</h1>;
}

// Usage
<Greeting message="React Developer" />
Hello, React Developer

Class Components: You can also use the ES6 class to define a component:

class Greeting extends React.Component {
  render() {
    return <h1>{`Hello, ${this.props.message}`}</h1>;
  }
}

// Usage
<Greeting message="React Developer" />
Hello, React Developer

State and Props Interview Questions

4. How to distinguish states and props? What is the exact use of props and states in React JS? Beginner

States and props are both used to handle data in React components but they have differences in their functionalities.

States: Used to handle data within a component. It is mutable. We can modify the state data using the setState() function.

Props: Used to pass data from parent to child components. They are immutable (read-only) from the child component's perspective.

Example - Props vs State:

import { useState } from 'react';

function Parent() {
  return <Child name="John" />;
}

function Child({ name }) {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Hello {name} (from props)</p>
      <p>Count: {count} (from state)</p>
      <button onClick={() => setCount(count + 1)}>Add</button>
    </div>
  );
}
Hello John (from props) Count: 0 (from state) [Add] - clicking increases count to 1, 2, 3...

5. What is the use of the state? Beginner

State is the simplest way to handle and store data in a React application. It allows for the creation of dynamic and responsive user interfaces.

Example - useState hook:

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
You clicked 0 times [Click me] - You clicked 1 times - You clicked 2 times...

6. What are the features of the state? Beginner

  • Enables re-rendering of components
  • Changes dynamically
  • Holds data

7. What is props drilling? Which is better - useContext or props? Intermediate

Props drilling refers to the process of passing data from a parent component to deeply nested child components. Each component in the hierarchy must pass the props down, even if only the last component in the chain needs the data.

Example - Props drilling problem:

function App() {
  const user = "John";
  return <Parent user={user} />;
}
function Parent({ user }) {
  return <Child user={user} />;
}
function Child({ user }) {
  return <p>Hello {user}</p>;
}
Hello John

Example - useContext solution:

import { createContext, useContext } from 'react';

const UserContext = createContext();

function App() {
  return (
    <UserContext.Provider value="John">
      <Parent />
    </UserContext.Provider>
  );
}
function Parent() {
  return <Child />;
}
function Child() {
  const user = useContext(UserContext);
  return <p>Hello {user}</p>;
}
Hello John

useContext is better for larger applications where multiple components need the same data. For simpler cases, passing props is fine.

Key Takeaway

Props drilling is passing data through multiple component layers. Use Context API for deeply nested data, but keep props for simple parent-child communication.

Interview Tip

Interviewers often ask this to test if you know state management patterns. Mention Context API, Redux, and Zustand as alternatives. Explain when each is appropriate.

React Hooks Interview Questions

8. What is a hook? What are major hooks? Beginner

React hooks are simple functions that allow functional components to use state, lifecycle methods, and other React features.

The major commonly used hooks are:

  • useState - Manage local state
  • useEffect - Handle side effects
  • useContext - Access context values
  • useReducer - Complex state logic
  • useCallback - Memoize functions
  • useMemo - Memoize computed values
  • useRef - Access DOM elements or persist values

Example - useEffect hook:

import { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return <p>Timer: {seconds}s</p>;
}
Timer: 0s - Timer: 1s - Timer: 2s - Timer: 3s...

Key Takeaway

Hooks let functional components use state and lifecycle features. useState and useEffect are the two most important hooks you must know.

Common Mistakes

  • Using class components when hooks can solve the problem simpler
  • Forgetting the dependency array in useEffect (causes infinite loops)
  • Not cleaning up effects (memory leaks)

Interview Tip

Be prepared to write a custom hook on the spot. Common follow-ups: useCallback vs useMemo, when to use useReducer over useState, and how to share logic between components.

9. What are the rules that must be followed when using hooks in React JS? Beginner

When using hooks in React JS we need to follow some important rules to avoid bugs:

  • Always call hooks at the top level of the program
  • Import the hook (import {useState} from 'react')
  • Do not call hooks inside loops, conditions, or nested functions
  • Only call hooks inside React functions
  • Add dependency arrays for useEffect and similar hooks

Example - Wrong vs Right:

// WRONG - hook inside condition
function App() {
  if (true) {
    const [count, setCount] = useState(0); // Error!
  }
}

// RIGHT - hook at top level
function App() {
  const [count, setCount] = useState(0);

  if (count > 5) {
    // conditional logic here is fine
  }
}
Wrong: React Hook "useState" is called conditionally. Right: Component renders without errors.

Lifecycle & Advanced React Interview Questions

10. Explain the lifecycle methods in React JS. Intermediate

Here are some popular lifecycle methods for enhancing and modifying components' behaviour:

  • componentDidMount() - Called after the component is rendered to the DOM
  • componentDidUpdate() - Called after a component re-renders due to state/prop changes
  • componentWillUnmount() - Called before a component is removed from the DOM
  • shouldComponentUpdate() - Determines if a re-render is needed

Example - Lifecycle in class component:

class UserProfile extends React.Component {
  componentDidMount() {
    console.log("Component mounted");
  }

  componentDidUpdate(prevProps) {
    if (prevProps.userId !== this.props.userId) {
      console.log("User ID changed");
    }
  }

  componentWillUnmount() {
    console.log("Component unmounting");
  }

  render() {
    return <h1>User: {this.props.userId}</h1>;
  }
}
On mount: "Component mounted" On prop change: "User ID changed" On removal: "Component unmounting"

Equivalent using hooks (modern approach):

import { useEffect } from 'react';

function UserProfile({ userId }) {
  useEffect(() => {
    console.log("Mounted / userId changed");
    return () => console.log("Cleanup");
  }, [userId]);

  return <h1>User: {userId}</h1>;
}
On mount: "Mounted / userId changed" On change: "Cleanup" then "Mounted / userId changed" On removal: "Cleanup"

11. Explain types of side effects in React components. Intermediate

In React, a side effect is any action like data fetching or DOM manipulation that affects something outside the component's rendering process. React uses the useEffect hook to handle side effects.

Side effects can be categorized as:

  • Mounting Side Effects: Occur on first render. Examples: data fetching, subscriptions, timers.
  • Updating Side Effects: Happen when props or state changes.
  • Cleaning Up Side Effects: Needed to avoid memory leaks when component unmounts.

Example - All three types:

import { useState, useEffect } from 'react';

function DataFetcher({ url }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    console.log("Fetching data...");
    fetch(url)
      .then(res => res.json())
      .then(json => setData(json));

    return () => console.log("Cleaning up...");
  }, [url]);

  return <pre>{JSON.stringify(data, null, 2)}</pre>;
}
Mount: "Fetching data..." then renders JSON URL changes: "Cleaning up..." then "Fetching data..." Unmount: "Cleaning up..."

12. What are higher-order components? Advanced

Higher-order components (HOCs) in React are a pattern used for reusing component logic. A HOC is a function that takes a component as input and returns a new component with additional functionality.

Example - HOC that adds loading state:

function withLoading(WrappedComponent) {
  return function({ isLoading, ...props }) {
    if (isLoading) {
      return <p>Loading...</p>;
    }
    return <WrappedComponent {...props} />;
  };
}

function UserList({ users }) {
  return (
    <ul>
      {users.map(u => <li key={u.id}>{u.name}</li>)}
    </ul>
  );
}

const UserListWithLoading = withLoading(UserList);

// Usage
<UserListWithLoading isLoading={true} users={[]} />
<UserListWithLoading isLoading={false} users={[{id:1, name:"John"}]} />
When isLoading=true: Loading... When isLoading=false: * John

Virtual DOM and Rendering

13. What is Virtual DOM? How does it work? Intermediate

The Virtual DOM is a lightweight JavaScript representation of the actual DOM. React creates a virtual copy of the DOM in memory and uses a diffing algorithm to compare changes before updating the real DOM.

How it works:

  • When state changes, React creates a new Virtual DOM tree
  • It compares (diffs) the new tree with the previous one
  • Only the changed elements are updated in the real DOM (reconciliation)

Example:

function Counter() {
  const [count, setCount] = useState(0);
  // Only the <span> with count re-renders,
  // not the entire component tree
  return (
    <div>
      <h1>My Counter App</h1>
      <span>{count}</span>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}
My Counter App 0 [+] - only the "0" updates to "1", not the entire page

14. What is the difference between Virtual DOM and Real DOM? Intermediate

Virtual DOMReal DOM
Lightweight copy in memoryActual browser DOM
Updates are batched and fastUpdates are slow and expensive
Cannot directly update HTMLDirectly updates HTML
Uses diffing algorithmRe-renders entire tree on change
Minimal memory usage per updateHigh memory consumption

15. What is reconciliation in React? Intermediate

Reconciliation is the process React uses to update the DOM efficiently. When a component's state or props change, React compares the new Virtual DOM with the previous one and calculates the minimum number of operations needed to update the real DOM.

Key rules React follows:

  • Elements of different types produce different trees (full re-render)
  • The developer can hint which elements are stable using the key prop
  • React only updates the attributes that changed on same-type elements

16. What is the key prop and why is it important? Intermediate

The key prop is a special attribute used when rendering lists. It helps React identify which items have changed, been added, or removed.

Example - Without vs With key:

// WRONG - no key
function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => <li>{todo.text}</li>)}
    </ul>
  );
}

// RIGHT - with unique key
function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => <li key={todo.id}>{todo.text}</li>)}
    </ul>
  );
}
Both render the same list, but with key React can efficiently update only changed items instead of re-rendering the entire list.

Components - Advanced Concepts

17. What are controlled and uncontrolled components? Intermediate

Controlled components have their form data handled by React state. Uncontrolled components store form data in the DOM itself.

Controlled component example:

function ControlledForm() {
  const [name, setName] = useState("");

  return (
    <input
      value={name}
      onChange={(e) => setName(e.target.value)}
    />
  );
}
Input value is always synced with React state. Typing "John" updates state to "John".

Uncontrolled component example:

function UncontrolledForm() {
  const inputRef = useRef(null);

  const handleSubmit = () => {
    alert(inputRef.current.value);
  };

  return (
    <div>
      <input ref={inputRef} />
      <button onClick={handleSubmit}>Submit</button>
    </div>
  );
}
Input value is accessed via ref only when needed (e.g., on submit).

18. What is conditional rendering in React? Beginner

Conditional rendering means displaying different UI based on certain conditions, similar to how conditions work in JavaScript.

Common patterns:

function Dashboard({ isLoggedIn, isAdmin }) {
  // 1. if/else
  if (!isLoggedIn) {
    return <p>Please log in</p>;
  }

  // 2. Ternary operator
  return (
    <div>
      {isAdmin ? <AdminPanel /> : <UserPanel />}

      {/* 3. Logical AND (short-circuit) */}
      {isAdmin && <p>Admin controls visible</p>}
    </div>
  );
}
If not logged in: "Please log in" If logged in + admin: AdminPanel + "Admin controls visible" If logged in + not admin: UserPanel

19. What are Pure Components in React? Intermediate

A Pure Component only re-renders when its props or state actually change. In class components, use React.PureComponent. In functional components, use React.memo().

Example:

// Functional pure component using React.memo
const UserCard = React.memo(function({ name, age }) {
  console.log("Rendering UserCard");
  return (
    <div>
      <h3>{name}</h3>
      <p>Age: {age}</p>
    </div>
  );
});

// Parent component
function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <UserCard name="John" age={25} />
      <button onClick={() => setCount(count + 1)}>Count: {count}</button>
    </div>
  );
}
"Rendering UserCard" logs only once on mount. Clicking the button updates count but does NOT re-render UserCard because its props did not change.

20. What are Error Boundaries in React? Advanced

Error Boundaries are React components that catch JavaScript errors in their child component tree, log them, and display a fallback UI instead of crashing the whole application.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.log("Error caught:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h2>Something went wrong.</h2>;
    }
    return this.props.children;
  }
}

// Usage
<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>
If MyComponent throws an error: "Something went wrong." If no error: MyComponent renders normally.

Common Mistakes

  • Trying to use Error Boundaries with hooks (they only work as class components)
  • Not placing Error Boundaries at meaningful levels (too high = generic error, too low = too many boundaries)
  • Forgetting that Error Boundaries do NOT catch errors in event handlers, async code, or SSR

Interview Tip

Mention that React does not have hook-based error boundaries yet. Libraries like react-error-boundary provide a hook-based API. Always explain where you would place them in a real app.

21. What is React.lazy() and Suspense? Advanced

React.lazy() allows you to load components lazily (on demand), reducing the initial bundle size. Suspense shows a fallback UI while the lazy component loads.

import React, { Suspense, lazy } from 'react';

// Lazy load the component
const HeavyChart = lazy(() => import('./HeavyChart'));

function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <Suspense fallback={<p>Loading chart...</p>}>
        <HeavyChart />
      </Suspense>
    </div>
  );
}
Initial load: "Dashboard" + "Loading chart..." After chunk loads: "Dashboard" + actual chart component

22. What are fragments in React? Beginner

Fragments let you group multiple elements without adding extra DOM nodes. This avoids unnecessary wrapper divs.

// Without Fragment (adds extra div)
function WithDiv() {
  return (
    <div>
      <h1>Title</h1>
      <p>Content</p>
    </div>
  );
}

// With Fragment (no extra DOM node)
function WithFragment() {
  return (
    <>
      <h1>Title</h1>
      <p>Content</p>
    </>
  );
}
WithDiv renders: <div><h1>Title</h1><p>Content</p></div> WithFragment renders: <h1>Title</h1><p>Content</p> (no wrapper)

Advanced Hooks Interview Questions

23. What is useReducer? When should you use it instead of useState? Intermediate

useReducer is a hook for managing complex state logic. Use it when state has multiple sub-values or when the next state depends on the previous one.

import { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    case 'reset':
      return { count: 0 };
    default:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </div>
  );
}
Count: 0 [+] [-] [Reset] Clicking +: Count: 1, Clicking -: Count: 0, Clicking Reset: Count: 0

24. What is useRef? What are its common use cases? Intermediate

useRef creates a mutable reference that persists across renders without causing re-renders when changed.

Common use cases:

  • Accessing DOM elements directly
  • Storing previous values
  • Keeping mutable values that do not trigger re-renders
import { useRef, useEffect } from 'react';

function AutoFocusInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus(); // Focus input on mount
  }, []);

  return <input ref={inputRef} placeholder="Auto-focused!" />;
}
Input field is automatically focused when the component mounts.

25. What is useCallback and when should you use it? Advanced

useCallback memoizes a function so it is not recreated on every render. Use it when passing callbacks to child components that rely on reference equality to prevent unnecessary re-renders.

import { useState, useCallback } from 'react';

function Parent() {
  const [count, setCount] = useState(0);

  // Without useCallback: new function on every render
  // const handleClick = () => setCount(count + 1);

  // With useCallback: same function reference
  const handleClick = useCallback(() => {
    setCount(prev => prev + 1);
  }, []);

  return <Child onClick={handleClick} />;
}

const Child = React.memo(({ onClick }) => {
  console.log("Child rendered");
  return <button onClick={onClick}>Click</button>;
});
"Child rendered" logs only once. Without useCallback, Child would re-render on every parent state change.

26. What is useMemo and how does it differ from useCallback? Advanced

useMemo memoizes a computed value. useCallback memoizes a function. Use useMemo for expensive calculations that should not re-run on every render.

import { useState, useMemo } from 'react';

function ExpensiveList({ items, filter }) {
  // Only recalculates when items or filter change
  const filteredItems = useMemo(() => {
    console.log("Filtering...");
    return items.filter(item => item.includes(filter));
  }, [items, filter]);

  return (
    <ul>
      {filteredItems.map(item => <li key={item}>{item}</li>)}
    </ul>
  );
}
"Filtering..." only logs when items or filter changes, not on every render.

27. How to create a custom hook in React? Intermediate

A custom hook is a JavaScript function starting with "use" that can call other hooks. It lets you extract reusable logic from components.

import { useState, useEffect } from 'react';

// Custom hook
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 Header() {
  const width = useWindowWidth();
  return <p>Window width: {width}px</p>;
}
Window width: 1200px (Resizing browser) Window width: 800px

React Router and Event Handling

28. What is React Router? How do you implement routing? Intermediate

React Router is a library for handling navigation in React applications. It enables single-page applications to have multiple views without full page reloads.

import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/contact">Contact</Link>
      </nav>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}
Clicking "About" link shows About component without page reload. URL changes to /about.

29. How does event handling work in React? Intermediate

React uses synthetic events - a cross-browser wrapper around native events. Events are named in camelCase and you pass functions (not strings) as handlers.

function EventExamples() {
  const handleClick = (e) => {
    e.preventDefault(); // Works same as native
    console.log("Button clicked");
  };

  const handleChange = (e) => {
    console.log("Input value:", e.target.value);
  };

  return (
    <div>
      <button onClick={handleClick}>Click Me</button>
      <input onChange={handleChange} />
    </div>
  );
}
Clicking button: "Button clicked" Typing in input: "Input value: H", "Input value: He", "Input value: Hel"...

30. What is event bubbling in React? How to stop it? Intermediate

Event bubbling means when an event occurs on an element, it propagates up through its parent elements. Use e.stopPropagation() to prevent it.

function BubblingExample() {
  return (
    <div onClick={() => console.log("Parent clicked")}>
      <button onClick={(e) => {
        e.stopPropagation(); // Prevents parent handler
        console.log("Button clicked");
      }}>
        Click Me
      </button>
    </div>
  );
}
Without stopPropagation: "Button clicked" then "Parent clicked" With stopPropagation: "Button clicked" only

React Performance Optimization

31. How to optimize performance in React applications? Advanced

Key techniques for optimizing React performance:

  • React.memo() - Prevent unnecessary re-renders of functional components
  • useMemo / useCallback - Memoize values and functions
  • Code splitting - Use React.lazy() and dynamic imports
  • Virtualization - Render only visible list items (react-window)
  • Avoid inline objects/functions - They create new references every render
  • Use keys properly - Stable, unique keys for lists

32. What causes unnecessary re-renders and how to prevent them? Advanced

Common causes of unnecessary re-renders:

  • Parent component re-rendering (all children re-render by default)
  • Creating new objects/arrays/functions in render
  • Not using React.memo for pure components
  • Context value changing (all consumers re-render)
// Problem: new object on every render
function App() {
  const [count, setCount] = useState(0);
  // This creates a new style object every render:
  return <Child style={{ color: "red" }} />;
}

// Solution: memoize or define outside
const style = { color: "red" }; // defined once
function App() {
  const [count, setCount] = useState(0);
  return <Child style={style} />;
}
With memoized style: Child renders once. Without memoization: Child re-renders every time parent state changes.

State Management

33. What is Redux? When should you use it? Intermediate

Redux is a predictable state management library. Use it when your application has complex state shared across many components and prop drilling becomes impractical.

Core concepts:

  • Store - Single source of truth for application state
  • Actions - Objects describing what happened
  • Reducers - Pure functions that specify how state changes
  • Dispatch - Method to send actions to the store
// Action
const increment = { type: 'INCREMENT' };

// Reducer
function counterReducer(state = { count: 0 }, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
}

// Usage in component
function Counter() {
  const count = useSelector(state => state.count);
  const dispatch = useDispatch();

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
    </div>
  );
}
0 [+] - clicking shows 1, 2, 3... State is managed globally via Redux store.

Key Takeaway

Redux = predictable state container. Use it for complex apps with lots of shared state. For simpler apps, Context API or Zustand may be better choices.

Common Mistakes

  • Using Redux for everything (overkill for small apps)
  • Mutating state directly in reducers instead of returning new objects
  • Not using Redux Toolkit (modern Redux) and writing too much boilerplate

Interview Tip

Modern interviews expect you to know Redux Toolkit, not legacy Redux. Also compare with alternatives: Zustand, Jotai, Recoil. Explain the one-way data flow: Action -> Reducer -> Store -> View.

34. What is the Context API? How does it compare to Redux? Advanced

The Context API is built into React for passing data through the component tree without prop drilling. It is simpler than Redux but less suited for high-frequency updates.

Context APIRedux
Built into ReactExternal library
Simple setupMore boilerplate
Good for low-frequency updates (theme, auth)Good for frequent, complex state changes
All consumers re-render on value changeOnly subscribed components re-render
No middleware supportSupports middleware (thunk, saga)

35. What is lifting state up in React? Intermediate

Lifting state up means moving state to the closest common ancestor of components that need to share it. This is the React pattern for sharing state between sibling components.

function Parent() {
  const [temperature, setTemperature] = useState("");

  return (
    <div>
      <CelsiusInput temp={temperature} onTempChange={setTemperature} />
      <FahrenheitDisplay temp={temperature} />
    </div>
  );
}

function CelsiusInput({ temp, onTempChange }) {
  return <input value={temp} onChange={e => onTempChange(e.target.value)} />;
}

function FahrenheitDisplay({ temp }) {
  const fahrenheit = temp ? (parseFloat(temp) * 9/5 + 32).toFixed(1) : "";
  return <p>Fahrenheit: {fahrenheit}</p>;
}
Typing "100" in celsius input: Fahrenheit: 212.0

Forms and Data Fetching

36. How to handle forms in React? Intermediate

In React, form inputs are typically handled as controlled components where React state drives the input values.

function LoginForm() {
  const [formData, setFormData] = useState({
    email: "",
    password: ""
  });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log("Submitted:", formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="email" value={formData.email} onChange={handleChange} />
      <input name="password" type="password" value={formData.password} onChange={handleChange} />
      <button type="submit">Login</button>
    </form>
  );
}
Filling form and clicking Login: Submitted: { email: "user@test.com", password: "123456" }

37. How to fetch data from an API in React? Intermediate

Use the useEffect hook combined with fetch or axios to load data when a component mounts.

import { useState, useEffect } from 'react';

function UserList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => {
        if (!res.ok) throw new Error("Failed to fetch");
        return res.json();
      })
      .then(data => {
        setUsers(data);
        setLoading(false);
      })
      .catch(err => {
        setError(err.message);
        setLoading(false);
      });
  }, []);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error}</p>;

  return (
    <ul>
      {users.map(user => <li key={user.id}>{user.name}</li>)}
    </ul>
  );
}
Loading... (after fetch completes) * Leanne Graham * Ervin Howell * Clementine Bauch ...

38. What is the difference between useEffect and useLayoutEffect? Intermediate

useEffect runs asynchronously after the browser paints. useLayoutEffect runs synchronously before the browser paints.

useEffectuseLayoutEffect
Runs after paintRuns before paint
Non-blocking (async)Blocking (sync)
Use for data fetching, subscriptionsUse for DOM measurements, preventing flicker
Preferred in most casesUse only when needed
import { useLayoutEffect, useRef } from 'react';

function Tooltip() {
  const ref = useRef();

  // Use useLayoutEffect to measure DOM before user sees it
  useLayoutEffect(() => {
    const { height } = ref.current.getBoundingClientRect();
    console.log("Element height:", height);
    // Position tooltip based on measurement
  }, []);

  return <div ref={ref}>Tooltip content</div>;
}
Element height: 24 (Tooltip is positioned correctly without visible flicker)

Testing and Design Patterns

39. How to test React components? Advanced

React components are commonly tested using React Testing Library along with Jest. The approach focuses on testing behavior from the user's perspective.

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

test('increments counter on button click', () => {
  render(<Counter />);

  // Find elements like a user would
  const button = screen.getByText("Click me");
  const count = screen.getByText("You clicked 0 times");

  // Simulate user action
  fireEvent.click(button);

  // Assert the result
  expect(screen.getByText("You clicked 1 times")).toBeInTheDocument();
});
PASS increments counter on button click (25ms)

40. What are render props in React? Intermediate

Render props is a pattern where a component receives a function as a prop that returns a React element. It allows sharing behavior between components.

// Component with render prop
function MouseTracker({ render }) {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (e) => {
    setPosition({ x: e.clientX, y: e.clientY });
  };

  return (
    <div onMouseMove={handleMouseMove} style={{ height: "100vh" }}>
      {render(position)}
    </div>
  );
}

// Usage
<MouseTracker render={({ x, y }) => (
  <p>Mouse position: {x}, {y}</p>
)} />
Mouse position: 245, 312 (updates as mouse moves)

41. What is the difference between class components and functional components? Intermediate

Class ComponentsFunctional Components
Use ES6 class syntaxUse plain JavaScript functions
Have lifecycle methodsUse hooks (useEffect)
Use this.state and this.setStateUse useState hook
Can have refs directlyUse useRef hook
More boilerplate codeCleaner, less code
Harder to reuse logicCustom hooks for reusable logic

Modern React recommends functional components with hooks for all new code.

42. What is the spread operator and how is it used in React? Beginner

The spread operator (...) is used to pass all properties of an object as individual props, copy objects/arrays immutably, and merge state updates.

// Passing all props
const buttonProps = { type: "submit", className: "btn", disabled: false };
<button {...buttonProps}>Submit</button>

// Immutable state update
const [user, setUser] = useState({ name: "John", age: 25, city: "NYC" });

// Update only age, keep rest unchanged
setUser(prev => ({ ...prev, age: 26 }));
// Result: { name: "John", age: 26, city: "NYC" }
Button renders with type="submit", className="btn", disabled=false User state: { name: "John", age: 26, city: "NYC" }

Modern React (2025-2026)

43. What are React Server Components? Advanced

React Server Components (RSC) are components that render on the server and send only the HTML to the client. They reduce JavaScript bundle size and improve initial load performance.

Key differences from client components:

  • Cannot use hooks (useState, useEffect)
  • Cannot use browser APIs
  • Can directly access databases and file systems
  • Send zero JavaScript to the client
  • Use "use server" directive
// Server Component (default in Next.js App Router)
async function UserProfile({ userId }) {
  // Can fetch directly - no useEffect needed
  const user = await db.query("SELECT * FROM users WHERE id = $1", [userId]);

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
}

// Client Component (needs interactivity)
"use client";
function LikeButton() {
  const [liked, setLiked] = useState(false);
  return <button onClick={() => setLiked(!liked)}>{liked ? "Liked" : "Like"}</button>;
}
Server Component: Renders HTML directly, no JS sent to browser. Client Component: Interactive, JS bundle sent to browser.

Interview Tip

This is a hot topic in 2026 interviews. Know the difference between Server and Client Components, when to use "use client", and how frameworks like Next.js implement RSC.

44. What is the useTransition hook? Advanced

useTransition lets you mark state updates as non-urgent transitions. The UI remains responsive during expensive re-renders by keeping the old UI visible until the new one is ready.

import { useState, useTransition } from 'react';

function SearchResults() {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState([]);
  const [isPending, startTransition] = useTransition();

  const handleChange = (e) => {
    setQuery(e.target.value); // urgent: update input immediately

    startTransition(() => {
      // non-urgent: can be interrupted
      setResults(filterLargeList(e.target.value));
    });
  };

  return (
    <div>
      <input value={query} onChange={handleChange} />
      {isPending && <p>Updating...</p>}
      <ul>{results.map(r => <li key={r}>{r}</li>)}</ul>
    </div>
  );
}
Typing is instant (urgent update). List filtering happens in background (transition). "Updating..." shows while filtering large data.

45. What is React.forwardRef? Intermediate

forwardRef lets a component pass a ref to a child component. This is needed because refs cannot be passed as regular props.

import { forwardRef, useRef } from 'react';

// Child component that accepts a ref
const CustomInput = forwardRef(function(props, ref) {
  return <input ref={ref} placeholder={props.placeholder} />;
});

// Parent component
function Form() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <CustomInput ref={inputRef} placeholder="Type here..." />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}
Clicking "Focus Input" focuses the input inside CustomInput component.

46. What is the difference between useMemo and React.memo? Intermediate

They solve different problems:

React.memouseMemo
Higher-order componentHook
Memoizes entire component renderingMemoizes a computed value
Prevents re-render if props unchangedPrevents recalculation if dependencies unchanged
Wraps component: React.memo(MyComp)Used inside component: useMemo(() => calc(), [deps])
// React.memo - prevents component re-render
const ExpensiveList = React.memo(function({ items }) {
  return items.map(i => <li key={i.id}>{i.name}</li>);
});

// useMemo - prevents value recalculation
function Dashboard({ data }) {
  const total = useMemo(() => {
    return data.reduce((sum, item) => sum + item.price, 0);
  }, [data]);

  return <p>Total: ${total}</p>;
}
React.memo: Component skips re-render if items prop is same. useMemo: total only recalculates when data changes.

47. What is StrictMode in React? Beginner

StrictMode is a development-only tool that highlights potential problems in your application. It does not render any visible UI and does not affect production builds.

What it detects:

  • Unsafe lifecycle methods
  • Legacy string ref usage
  • Side effects in render phase (double-invokes components)
  • Deprecated APIs
import { StrictMode } from 'react';

function App() {
  return (
    <StrictMode>
      <MainContent />
    </StrictMode>
  );
}
In development: components render twice to detect side effects. In production: no effect, no performance impact.

48. What is the useId hook? Beginner

useId generates unique IDs that are stable across server and client rendering. It solves the problem of ID mismatches during hydration in SSR apps.

import { useId } from 'react';

function FormField({ label }) {
  const id = useId();

  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <input id={id} type="text" />
    </div>
  );
}

// Using multiple times generates unique IDs
<FormField label="Name" />  // id=":r1:"
<FormField label="Email" /> // id=":r2:"
Each FormField gets a unique, stable ID. No hydration mismatch between server and client.

49. What is prop types validation in React? Beginner

PropTypes is a runtime type-checking library for React props. It warns in development if a component receives props of the wrong type.

import PropTypes from 'prop-types';

function UserCard({ name, age, isAdmin }) {
  return (
    <div>
      <h3>{name}</h3>
      <p>Age: {age}</p>
      {isAdmin && <span>Admin</span>}
    </div>
  );
}

UserCard.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number.isRequired,
  isAdmin: PropTypes.bool
};

UserCard.defaultProps = {
  isAdmin: false
};
If name is missing: Warning: Failed prop type: The prop `name` is marked as required. Note: Modern React prefers TypeScript over PropTypes for type safety.

Interview Tip

While PropTypes still works, most companies now use TypeScript for type safety. Mention both approaches and explain why TypeScript is preferred (compile-time vs runtime checking).

50. What is React Portals? Intermediate

Portals let you render children into a DOM node outside the parent component's DOM hierarchy. This is commonly used for modals, tooltips, and dropdown menus.

import { createPortal } from 'react-dom';

function Modal({ children, isOpen }) {
  if (!isOpen) return null;

  return createPortal(
    <div className="modal-overlay">
      <div className="modal-content">
        {children}
      </div>
    </div>,
    document.getElementById('modal-root') // renders outside #app-root
  );
}

// Usage
function App() {
  const [showModal, setShowModal] = useState(false);
  return (
    <div>
      <button onClick={() => setShowModal(true)}>Open</button>
      <Modal isOpen={showModal}>
        <p>This renders outside the App DOM tree!</p>
      </Modal>
    </div>
  );
}
Modal renders inside #modal-root (outside #app-root in the DOM). Events still bubble up through the React component tree normally.

Common Mistakes

  • Forgetting to add the portal target element in index.html
  • Not handling keyboard events (Escape to close) for accessibility
  • Not trapping focus inside the modal

51. What is the difference between useEffect and event handlers? Intermediate

Event handlers run in response to user actions (clicks, typing). useEffect runs after render to synchronize with external systems.

Event HandlersuseEffect
Triggered by user actionTriggered by rendering
Run specific code on interactionSynchronize with external system
E.g., submit form, navigateE.g., fetch data, set up subscription
No cleanup neededMay need cleanup function
function ChatRoom({ roomId }) {
  // Event handler: runs when user clicks
  const sendMessage = () => {
    postMessage(roomId, message);
  };

  // Effect: synchronize with chat server
  useEffect(() => {
    const connection = createConnection(roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return <button onClick={sendMessage}>Send</button>;
}
Effect: connects/disconnects automatically when roomId changes. Event handler: sends message only when user clicks button.

52. How to prevent prop drilling without Context or Redux? Intermediate

Alternative patterns to avoid prop drilling:

  • Component Composition - Pass components as children instead of data
  • Render Props - Pass a function that returns JSX
  • Custom Hooks - Share logic without passing props
  • URL State - Store state in URL params (React Router)
// Component Composition (best alternative)
// Instead of passing user through 3 levels:
function App() {
  const user = useUser();

  return (
    <Layout>
      <Header>
        <UserAvatar name={user.name} />
      </Header>
      <Sidebar>
        <UserMenu permissions={user.permissions} />
      </Sidebar>
    </Layout>
  );
}

// Layout and Sidebar never know about user!
function Layout({ children }) {
  return <div className="layout">{children}</div>;
}
function Sidebar({ children }) {
  return <aside>{children}</aside>;
}
Layout and Sidebar are generic containers. User data is passed directly to the components that need it. No intermediate components touch user props.

Interview Tip

Component composition is the React team's recommended solution before reaching for Context. Show that you understand the tradeoffs: composition for UI structure, Context for truly global data (theme, auth), Redux for complex state machines.

Official Resources & Further Reading

To dive deeper into React JS concepts covered in this interview guide, refer to these official and authoritative resources:

Tip: Bookmark the React Blog to stay updated with the latest React releases, features, and best practices.