React Interview Questions and Answers

Components, hooks, rendering behaviour, state management, concurrent features and modern React ecosystem.

Practise 10 random 75 peer-reviewed questions
React Interview Syllabus & Preparation Strategy

Whether you are preparing for entry-level React interview questions for freshers or senior software engineer interview questions addressing concurrency, scalability, and system architecture, this track provides peer-reviewed model answers with syntax walkthroughs, edge cases, and practical interview tips.

1 What are Pure Components? Medium

Pure components are the components which render the same output for the same state and props. In function components, you can achieve these pure components through memoized React.memo() API wrapping around the component. This API prevents unnecessary re-renders by comparing the previous props and new props using shallow comparison. So it will be helpful for performance optimizations.

But at the same time, it won't compare the previous state with the current state because function component itself prevents the unnecessary rendering by default when you set the same state again.

The syntactic representation of memoized components looks like below,

    const MemoizedComponent = memo(SomeComponent, arePropsEqual?);
    

Below is the example of how child component(i.e., EmployeeProfile) prevents re-renders for the same props passed by parent component(i.e.,EmployeeRegForm).

    import { memo, useState } from "react";

    const EmployeeProfile = memo(function EmployeeProfile({ name, email }) {
      return (
        <>
          <p>Name:{name}</p>
          <p>Email: {email}</p>
        </>
      );
    });
    export default function EmployeeRegForm() {
      const [name, setName] = useState("");
      const [email, setEmail] = useState("");
      return (
        <>
          <label>
            Name:{" "}
            <input value={name} onChange={(e) => setName(e.target.value)} />
          </label>
          <label>
            Email:{" "}
            <input value={email} onChange={(e) => setEmail(e.target.value)} />
          </label>
          <hr />
          <EmployeeProfile name={name} />
        </>
      );
    }
    

In the above code, the email prop has not been passed to child component. So there won't be any re-renders for email prop change.

In class components, the components extending _React.PureComponent_ instead of _React.Component_ become the pure components. When props or state changes, _PureComponent_ will do a shallow comparison on both props and state by invoking shouldComponentUpdate() lifecycle method.

Note: React.memo() is a higher-order component.

2 What are controlled components? Medium

A controlled component is a React component that fully manages the form element's state(e.g, elements like <input>, <textarea>, or <select>)) using React's internal state mechanism. i.e, The component does not manage its own internal state — instead, React acts as the single source of truth for form data.

The controlled components will be implemented using the below steps,

  1. Initialize the state using useState hooks in function components or inside constructor for class components.
  2. Set the value of the form element to the respective state variable.
  3. Create an event handler(onChange) to handle the user input changes through useState's updater function or setState from class component.
  4. Attach the above event handler to form element's change or click events

Note: React re-renders the component every time the input value changes.

For example, the name input field updates the username using handleChange event handler as below,

   import React, { useState } from "react";

   function UserProfile() {
     const [username, setUsername] = useState("");

     const handleChange = (e) => {
       setUsername(e.target.value);
     };

     return (
       <form>
         <label>
           Name:
           <input type="text" value={username} onChange={handleChange} />
         </label>
       </form>
     );
   }
   

In these components, DOM does not hold the actual data instead React does.

Benefits:

  • Easy to implement validation, conditional formatting, or live feedback.
  • Full control over form data.
  • Easier to test and debug because the data is centralized in the component’s state.
3 What are uncontrolled components? Medium

The Uncontrolled components are form elements (like <input>, <textarea>, or <select>) that manage their own state internally via the DOM, rather than through React state.
You can query the DOM using a ref to find its current value when you need it. This is a bit more like traditional HTML.

The uncontrolled components will be implemented using the below steps,

  1. Create a ref using useRef react hook in function component or React.createRef() in class based component.
  2. Attach this ref to the form element.
  3. The form element value can be accessed directly through ref in event handlers or componentDidMount for class components

In the below UserProfile component, the username input is accessed using ref.

```jsx harmony
import React, { useRef } from "react";

function UserProfile() {
const usernameRef = useRef(null);

const handleSubmit = (event) => {
event.preventDefault();
console.log("The submitted username is: " + usernameRef.current.value);
};

return (
<form onSubmit={handleSubmit}>
<label>
Username:
<input type="text" ref={usernameRef} />
</label>
<button type="submit">Submit</button>
</form>
);
}

    **Note:** Here, DOM is in charge of the value. React only accesses the value when needed (via `ref`).

    **Benefits:**
     *   **Less boilerplate** — no need for `useState` and `onChange`.
     *   Useful for **quick form setups** or when integrating with **non-React code**.
     *   Slightly better **performance** in very large forms (fewer re-renders).

    In most cases, it's recommend to use controlled components to implement forms. In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself.

    <details><summary><b>See Class</b></summary>
    <p>

    
jsx harmony
class UserProfile extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.input = React.createRef();
}

handleSubmit(event) {
alert("A name was submitted: " + this.input.current.value);
event.preventDefault();
}

render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
{"Name:"}
<input type="text" ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
```

</p>
</details>

4 Does the lazy function support named exports? Medium

No, currently React.lazy function supports default exports only. If you would like to import modules which are named exports, you can create an intermediate module that reexports it as the default. It also ensures that tree shaking keeps working and don’t pull unused components.
Let's take a component file which exports multiple named components,

    // MoreComponents.js
    export const SomeComponent = /* ... */;
    export const UnusedComponent = /* ... */;
    

and reexport MoreComponents.js components in an intermediate file IntermediateComponent.js

    // IntermediateComponent.js
    export { SomeComponent as default } from "./MoreComponents.js";
    

Now you can import the module using lazy function as below,

    import React, { lazy } from "react";
    const SomeComponent = lazy(() => import("./IntermediateComponent.js"));
    
5 What are portals in React? Medium

A Portal is a React feature that enables rendering children into a DOM node that exists outside the parent component's DOM hierarchy, while still preserving the React component hierarchy. Portals help avoid CSS stacking issues—for example, elements with position: fixed may not behave as expected inside a parent with transform. Portals solve this by rendering content (like modals or tooltips) outside such constrained DOM contexts.

    ReactDOM.createPortal(child, container);
    
  • child: Any valid React node (e.g., JSX, string, fragment).
  • container: A real DOM node (e.g., document.getElementById('modal-root')).

Even though the content renders elsewhere in the DOM, it still behaves like a normal child in React. It has access to context, state, and event handling.

Example:- Modal:

    function Modal({ children }) {
      return ReactDOM.createPortal(
        <div className="modal">{children}</div>,
        document.body)
      );
    }
    

The above code will render the modal content into the body element in the HTML, not inside the component's usual location.

6 Do Hooks replace render props and higher order components? Medium

Both render props and higher-order components render only a single child but in most of the cases Hooks are a simpler way to serve this by reducing nesting in your tree.

7 What is the difference between React context and React Redux? Medium

You can use Context in your application directly and is going to be great for passing down data to deeply nested components which what it was designed for.

Whereas Redux is much more powerful and provides a large number of features that the Context API doesn't provide. Also, React Redux uses context internally but it doesn't expose this fact in the public API.

| Aspect | Context API | Redux |
| --- | --- | --- |
| Purpose | Dependency injection — passes data through the tree without prop drilling | Full state-management library with a predictable, centralized store |
| State updates | Plain useState/useReducer next to the provider; no built-in middleware | Actions + reducers, with middleware support (redux-thunk, redux-saga, etc.) |
| Performance | Every consumer re-renders on any value change unless you split contexts/memoize | Uses selectors (useSelector/connect) so components only re-render when the selected slice changes |
| DevTools | None built-in | Time-travel debugging, action logs via Redux DevTools |
| Async logic | You wire it yourself (custom hooks, effects) | Standardized patterns via middleware |
| Boilerplate | Minimal — just createContext/useContext | More setup, though Redux Toolkit reduces this significantly |

#### Does Context replace Redux?

Not entirely — they solve overlapping but different problems, so the right choice depends on the app's needs:

  • Context is a good fit for low-frequency, mostly-static data that many components need (theme, locale, authenticated user, feature flags). Combined with useReducer, it can even model simple local/global state without pulling in Redux (see [Can you combine useReducer with useContext?](#can-you-combine-usereducer-with-usecontext)).
  • Redux is still preferable for large apps with complex, frequently-updating state, cross-cutting concerns like caching/undo/logging, a need for middleware (async flows, side effects), or debugging tools like time-travel and action replay.
  • Performance matters: Context has no built-in mechanism to prevent unnecessary re-renders of all consumers when the provided value changes, whereas Redux's useSelector re-renders only the components that depend on the changed slice of state.

In short, Context is a simpler tool for prop-drilling/dependency-injection use cases, while Redux remains a more robust, scalable option for complex application-wide state management. Many apps use both together — Context for simple, rarely-changing values and Redux (or another store) for the rest.

8 What is React lazy function? Medium

The React.lazy function lets you render a dynamic import as a regular component. It will automatically load the bundle containing the OtherComponent when the component gets rendered. This must return a Promise which resolves to a module with a default export containing a React component.

     const OtherComponent = React.lazy(() => import("./OtherComponent"));

     function MyComponent() {
       return (
         <div>
           <OtherComponent />
         </div>
       );
     }
     

Note:
React.lazy and Suspense is not yet available for server-side rendering. If you want to do code-splitting in a server rendered app, we still recommend React Loadable.

9 What are hooks? Medium

Hooks is a special JavaScript function that allows you use state and other React features without writing a class. This pattern has been introduced as a new feature in React 16.8 and helped to isolate the stateful logic from the components.

Let's see an example of useState hook:

     import { useState } from "react";

     function Example() {
       // Declare a new state variable, which we'll call "count"
       const [count, setCount] = useState(0);

       return (
         <>
           <p>You clicked {count} times</p>
           <button onClick={() => setCount(count + 1)}>Click me</button>
         </>
       );
     }
     

Note: Hooks can be used inside an existing function component without rewriting the component.

10 What rules need to be followed for hooks? Medium

You need to follow two rules in order to use hooks,

  1. Call Hooks only at the top level of your react functions: You should always use hooks at the top level of react function before any early returns. i.e, You shouldn’t call Hooks inside loops, conditions, or nested functions. This will ensure that Hooks are called in the same order each time a component renders and it preserves the state of Hooks between multiple re-renders due to useState and useEffect calls.

Let's see the difference using an example,
Correct usage::

     function UserProfile() {
      // Correct: Hooks called at the top level
      const [name, setName] = useState('John');
      const [country, setCountry] = useState('US');

      return (
        <div>
          <h1>Name: {name}</h1>
          <p>Country: {country}</p>
        </div>
      );
     }
     

Incorrect usage::

     function UserProfile() {
      const [name, setName] = useState('John');

      if (name === 'John') {
        // Incorrect: useState is called inside a conditional
        const [country, setCountry] = useState('US'); 
      }

      return (
        <div>
          <h1>Name: {name}</h1>
          <p>Country: {country}</p> {/* This will throw an error if the name condition isn't met */}
        </div>
      );
     }
     

The useState hook for the country field is being called conditionally within an if block. This can lead to inconsistent state behavior and may cause hooks to be called in a different order on each re-render.

  1. Call Hooks from React Functions only: You shouldn’t call Hooks from regular JavaScript functions or class components. Instead, you should call them from either function components or custom hooks.

Let's find the difference of correct and incorrect usage with below examples,

Correct usage::

     //Example1:
     function Counter() {
      // Correct: useState is used inside a functional component
      const [count, setCount] = useState(0);

      return <div>Counter: {count}</div>;
     }
     //Example2:
     function useFetchData(url) {
      const [data, setData] = useState(null);

      useEffect(() => {
        fetch(url)
          .then((response) => response.json())
          .then((data) => setData(data));
      }, [url]);

      return data;
     }

     function UserProfile() {
      // Correct: Using a custom hook here
      const user = useFetchData('https://some-api.com/user');

      return (
        <div>
          <h1>{user ? user.name : 'Loading profile...'}</h1>
        </div>
      );
     }
     

Incorrect usage::

      //Example1
      function normalFunction() {
        // Incorrect: Can't call hooks in normal functions
        const [count, setCount] = useState(0); 
      }

      //Example2
      function fetchData(url) {
        // Incorrect: Hooks can't be used in non-React functions
        const [data, setData] = useState(null);

        useEffect(() => {
          fetch(url)
            .then((response) => response.json())
            .then((data) => setData(data));
        }, [url]);

        return data;
      }
     

In the above incorrect usage example, both useState and useEffect are used in non-React functions(normalFunction and fetchData), which is not allowed.

11 How to ensure hooks followed the rules in your project? Medium

React team released an ESLint plugin called eslint-plugin-react-hooks that enforces Hook's two rules. It is part of Hooks API. You can add this plugin to your project using the below command,

        npm install eslint-plugin-react-hooks --save-dev
        

And apply the below config in your ESLint config file,

        // Your ESLint configuration
        {
          "plugins": [
            // ...
            "react-hooks"
          ],
          "rules": {
            // ...
            "react-hooks/rules-of-hooks": "error"
          }
        }
        

This plugin also provide another important rule through react-hooks/exhaustive-deps. It ensures that the dependencies of useEffect, useCallback, and useMemo hooks are correctly listed to avoid potential bugs.

        useEffect(() => {
          // Forgetting `message` will result in incorrect behavior
          console.log(message);
        }, []); // Here `message` should be a dependency
        

The recommended eslint-config-react-app preset already includes the hooks rules of this plugin.
For example, the linter enforce proper naming convention for hooks. If you rename your custom hooks which as prefix "use" to something else then linter won't allow you to call built-in hooks such as useState, useEffect etc inside of your custom hook anymore.

Note: This plugin is intended to use in Create React App by default.

12 Can you describe about componentDidCatch lifecycle method signature? Medium

The componentDidCatch lifecycle method is invoked after an error has been thrown by a descendant component. The method receives two parameters,

  1. error: - The error object which was thrown
  2. info: - An object with a componentStack key contains the information about which component threw the error.

The method structure would be as follows

     componentDidCatch(error, info);
     
13 What is the benefit of component stack trace from error boundary? Medium

Apart from error messages and javascript stack, React16 will display the component stack trace with file names and line numbers using error boundary concept.

For example, BuggyCounter component displays the component stack trace as below,

![stacktrace](images/error_boundary.png)

14 What is the purpose of default value in context? Medium

The defaultValue argument is only used when a component does not have a matching Provider above it in the tree. This can be helpful for testing components in isolation without wrapping them.

Below code snippet provides default theme value as Luna.

     const MyContext = React.createContext(defaultValue);
     
15 What are the problems of using render props with pure components? Medium

If you create a function inside a render method, it negates the purpose of pure component. Because the shallow prop comparison will always return false for new props, and each render in this case will generate a new value for the render prop. You can solve this issue by defining the render function as instance method.

     class Mouse extends React.PureComponent {
       render() {
         // BAD: a new arrow function reference is created on every render,
         // so PureComponent's shallow comparison always sees "new" props
         return <MouseTracker render={(mouse) => <Cat mouse={mouse} />} />;
       }
     }
     
     class MouseWithCat extends React.PureComponent {
       // GOOD: defined once as an instance method/class property, so the
       // reference stays stable across renders
       renderTheCat = (mouse) => <Cat mouse={mouse} />;

       render() {
         return <MouseTracker render={this.renderTheCat} />;
       }
     }
     
16 What is the typical use case of portals? Medium

React Portals are primarily used to render UI components such as modals, tooltips, dropdowns, hovercards, and notifications outside of their parent component's DOM tree. This helps avoid common CSS issues caused by parent elements, such as:

  • overflow: hidden on parent elements clipping or hiding child elements like modals or tooltips,
  • stacking context and z-index conflicts created by parent containers that prevent child elements from appearing above other content.

That means, you need to visually “break out” of its container. By rendering these UI elements into a separate DOM node (often directly under <body>), portals ensure they appear above all other content and are not restricted by the parent’s CSS or layout constraints, resulting in correct positioning and visibility regardless of the parent’s styling.

17 How do you set default value for uncontrolled component? Medium

In React, the value attribute on form elements will override the value in the DOM. With an uncontrolled component, you might want React to specify the initial value, but leave subsequent updates uncontrolled. To handle this case, you can specify a defaultValue attribute instead of value.

     render() {
       return (
         <form onSubmit={this.handleSubmit}>
           <label>
             User Name:
             <input
               defaultValue="John"
               type="text"
               ref={this.input} />
           </label>
           <input type="submit" value="Submit" />
         </form>
       );
     }
     

The same applies for select and textArea inputs. But you need to use defaultChecked for checkbox and radio inputs.

18 Do I need to rewrite all my class components with hooks? Medium

No. But you can try Hooks in a few components(or new components) without rewriting any existing code. Because there are no plans to remove classes in ReactJS.

19 What is useEffect hook? How to fetch data with React Hooks? Medium

The useEffect hook is a React Hook that lets you perform side effects in function components. Side effects are operations that interact with the outside world or system and aren't directly related to rendering UI — such as fetching data, setting up subscriptions, timers, manually manipulating the DOM, etc.

In function components, useEffect replaces the class component lifecycle methods(componentDidMount, componentDidUpdate and componentWillUnmount) with a single, unified API.

Syntax

     useEffect(() => {
        // Side effect logic here

        return () => {
        // Cleanup logic (optional)
        };
        }, [dependencies]);
     

This effect hook can be used to fetch data from an API and to set the data in the local state of the component with the useState hook’s update function.

Here is an example of fetching a list of ReactJS articles from an API using fetch.

     import React from "react";

     function App() {
       const [data, setData] = React.useState({ hits: [] });

       React.useEffect(() => {
         fetch("http://hn.algolia.com/api/v1/search?query=react")
           .then((response) => response.json())
           .then((data) => setData(data));
       }, []);

       return (
         <ul>
           {data.hits.map((item) => (
             <li key={item.objectID}>
               <a href={item.url}>{item.title}</a>
             </li>
           ))}
         </ul>
       );
     }

     export default App;
     

A popular way to simplify this is by using the library axios.

We provided an empty array as second argument to the useEffect hook to avoid activating it on component updates. This way, it only fetches on component mount.

20 Is Hooks cover all use cases for classes? Medium

Hooks doesn't cover all use cases of classes but there is a plan to add them soon. Currently there are no Hook equivalents to the uncommon getSnapshotBeforeUpdate and componentDidCatch lifecycles yet.

Showing 20 of 75 questions

Frequently Asked Questions About React Interviews

What do hiring managers evaluate in React technical rounds?

Technical interviewers look for foundational fluency, idiomatic syntax, clarity when communicating complex logic, and awareness of performance trade-offs (e.g. memory footprint, render performance, and network latency) in production environments.

What are the best interview tips for practicing React questions?

Use active recall: summarize each answer in your own words before revealing the model solution. Focus on explaining why a certain approach is chosen rather than just memorizing code syntax.