ReactJS Interview Questions

author image Hirely
at 08 Jan, 2025

Question: What is the lifecycle of a React component?

Answer:

The lifecycle of a React component refers to the series of methods that are invoked at different stages of a component’s existence, from its creation (mounting) to its removal (unmounting) from the DOM. The component lifecycle methods provide developers with hooks for running code at specific times during a component’s life. These methods are available primarily in class components, but with the introduction of Hooks in React 16.8, functional components can now also manage lifecycle events.

Lifecycle Phases:

  1. Mounting:

    • This is the phase when a component is being created and inserted into the DOM for the first time.
  2. Updating:

    • This phase occurs when a component’s state or props change. React re-renders the component, and the lifecycle methods are triggered as part of this process.
  3. Unmounting:

    • This is the phase when a component is removed from the DOM.
  4. Error Handling:

    • React has lifecycle methods that catch JavaScript errors during rendering or in lifecycle methods, allowing for graceful error recovery.

Lifecycle Methods in Class Components:

1. Mounting Phase:

When a component is being created and inserted into the DOM, the following lifecycle methods are called:

  • constructor():

    • The first method called when a class component is created. It is used to initialize the component’s state and bind event handlers.
    • Example:
      constructor(props) {
        super(props);
        this.state = { count: 0 };
      }
  • static getDerivedStateFromProps(props, state):

    • This method is called before every render (both during mounting and updating). It allows the component to update its state based on changes in props.
    • Returns an object to update the state, or null to indicate no changes.
    • Example:
      static getDerivedStateFromProps(nextProps, nextState) {
        if (nextProps.count !== nextState.count) {
          return { count: nextProps.count };
        }
        return null;
      }
  • render():

    • This is the only required method in a class component. It returns the JSX that describes the UI.
    • Example:
      render() {
        return <h1>{this.state.count}</h1>;
      }
  • componentDidMount():

    • Called immediately after a component is added to the DOM. It is often used for operations like fetching data, setting up subscriptions, or manipulating the DOM.
    • Example:
      componentDidMount() {
        console.log("Component has mounted");
      }

2. Updating Phase:

This phase occurs when a component’s state or props change, leading to a re-render. The following lifecycle methods are called during updates:

  • static getDerivedStateFromProps(props, state):

    • As mentioned earlier, it is also called during updates before rendering to derive state from props.
  • shouldComponentUpdate(nextProps, nextState):

    • This method allows you to optimize performance by preventing unnecessary re-renders. If it returns false, React will skip rendering and updating the component.
    • Example:
      shouldComponentUpdate(nextProps, nextState) {
        return nextProps.count !== this.props.count;
      }
  • render():

    • The render() method is called again to reflect the updated state or props in the UI.
  • getSnapshotBeforeUpdate(prevProps, prevState):

    • This method is called right before the changes from the virtual DOM are committed to the real DOM. It allows you to capture information (like scroll position) before the update occurs.
    • Example:
      getSnapshotBeforeUpdate(prevProps, prevState) {
        return null;  // capture any value you want here
      }
  • componentDidUpdate(prevProps, prevState, snapshot):

    • This method is called immediately after the component is updated and re-rendered. It is often used for side effects like fetching data or manipulating the DOM after an update.
    • Example:
      componentDidUpdate(prevProps, prevState) {
        console.log("Component did update");
      }

3. Unmounting Phase:

This phase occurs when the component is being removed from the DOM.

  • componentWillUnmount():
    • This method is called just before the component is removed from the DOM. It is often used for cleanup tasks like clearing timers, canceling network requests, or removing subscriptions.
    • Example:
      componentWillUnmount() {
        console.log("Component will unmount");
      }

4. Error Handling:

React also provides lifecycle methods for error boundaries, which are used to catch errors during rendering or in lifecycle methods.

  • static getDerivedStateFromError(error):

    • This method is called when an error occurs during rendering, in lifecycle methods, or in constructors of any child components. It allows you to update state to indicate the error.
    • Example:
      static getDerivedStateFromError(error) {
        return { hasError: true };
      }
  • componentDidCatch(error, info):

    • This method is called after an error is caught. It provides a way to log the error and display fallback UI.
    • Example:
      componentDidCatch(error, info) {
        console.log("Error caught:", error, info);
      }

Component Lifecycle in Functional Components with Hooks:

In functional components, React’s Hooks API is used to manage state, side effects, and lifecycle events.

  • useState():
    • Used to manage local state in functional components. It replaces the state in class components.
  • useEffect():
    • This hook serves the purpose of lifecycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount in class components.
    • useEffect() runs after every render, but you can control when it runs by specifying dependencies.
    • Example:
      useEffect(() => {
        // Code to run after render (similar to componentDidMount)
        console.log('Component mounted or updated');
      
        // Cleanup (similar to componentWillUnmount)
        return () => {
          console.log('Cleanup before unmount');
        };
      }, [dependencies]); // Optional dependencies array

Summary of Class Component Lifecycle:

  • Mounting:

    • constructor()
    • static getDerivedStateFromProps()
    • render()
    • componentDidMount()
  • Updating:

    • static getDerivedStateFromProps()
    • shouldComponentUpdate()
    • render()
    • getSnapshotBeforeUpdate()
    • componentDidUpdate()
  • Unmounting:

    • componentWillUnmount()
  • Error Handling:

    • static getDerivedStateFromError()
    • componentDidCatch()

Summary for Functional Components:

  • Functional components use useState() for state and useEffect() for lifecycle management. The useEffect() hook is called after every render, but can be customized to act like different lifecycle methods depending on its dependencies.

The lifecycle methods in React allow you to hook into different stages of a component’s existence, providing flexibility and control over how the component behaves during its lifecycle.

Question: What is the use of useState in React?

Answer:

useState is a hook in React that allows functional components to manage and track state. Before the introduction of hooks, state could only be managed in class components, but with hooks, functional components can now also maintain state.

The useState hook is essential for creating interactive components where the state can change over time and trigger a re-render when it does.

Syntax:

const [state, setState] = useState(initialState);
  • state: This is the current value of the state variable.
  • setState: This is the function used to update the state. It takes the new state value (or a function that returns the new state) as its argument.
  • initialState: This is the initial value assigned to the state when the component is first rendered. It can be any type: a number, string, object, array, or even a function.

How useState Works:

  1. Initial State:

    • When the component is first rendered, the initialState is used to initialize the state variable.
  2. Updating State:

    • When you call setState, React schedules a re-render of the component, and the component’s state is updated with the new value. The new state will be reflected in the next render.
  3. Re-rendering:

    • Every time the state changes, React re-renders the component, reflecting the updated state in the UI.

Example:

Here’s a simple example of how useState is used to toggle a button text between “ON” and “OFF” based on user interaction:

import React, { useState } from 'react';

const ToggleButton = () => {
  // Declare a state variable 'isOn' and a function 'setIsOn' to update it
  const [isOn, setIsOn] = useState(false); // initial state is 'false'

  // Handler to toggle the 'isOn' state
  const toggle = () => {
    setIsOn(!isOn); // Toggle the value of 'isOn'
  };

  return (
    <button onClick={toggle}>
      {isOn ? 'ON' : 'OFF'} {/* Button text based on 'isOn' state */}
    </button>
  );
};

export default ToggleButton;

Breakdown:

  1. State Declaration:

    • const [isOn, setIsOn] = useState(false);
      • Here, isOn is the state variable that keeps track of whether the button is “ON” or “OFF.”
      • setIsOn is the function used to update the value of isOn.
  2. Updating State:

    • Inside the toggle function, setIsOn(!isOn) updates the state by toggling the current value of isOn.
  3. UI Update:

    • The button text dynamically updates based on the isOn state. If isOn is true, the button text will display “ON”, otherwise it will display “OFF.”

Important Points About useState:

  • Initial State: useState(initialState) takes an argument that defines the initial value of the state. If the initial state depends on props or other calculations, you can pass a function to useState that will return the initial state.

    Example:

    const [count, setCount] = useState(() => computeInitialCount());
  • State Updates Are Asynchronous: React batches state updates for performance reasons, so updates to the state might not be reflected immediately after calling setState. This means that you should not rely on the updated state right after setting it.

    Example of handling updates in sequence:

    setCount(prevCount => prevCount + 1);
  • State Can Be Any Data Type: The state managed with useState can be any type: a string, number, array, object, or even more complex types like a function.

    Example with an array:

    const [items, setItems] = useState([]);
    setItems([...items, newItem]);
  • Multiple States in a Component: You can use multiple useState calls in a single component to manage different pieces of state.

    Example with multiple states:

    const [count, setCount] = useState(0);
    const [name, setName] = useState('');
  • Functional Updates: If the new state depends on the previous state, you can use a functional update by passing a function to setState, which receives the current state as an argument and returns the new state.

    Example:

    setCount(prevCount => prevCount + 1);

Summary:

  • The useState hook enables functional components to manage state in React.
  • It returns a pair: the current state value and a function to update it.
  • useState can store various types of values, such as strings, numbers, arrays, objects, etc.
  • Updating state triggers a re-render of the component, reflecting the new state in the UI.
  • useState is fundamental for building interactive and dynamic applications in React.

By using useState, you can create more dynamic and responsive UI elements in functional components, making React a powerful library for building modern web applications.

Read More

If you can’t get enough from this article, Aihirely has plenty more related information, such as ReactJS interview questions, ReactJS interview experiences, and details about various ReactJS job positions. Click here to check it out.

Related Posts

Trace Job opportunities

Hirely, your exclusive interview companion, empowers your competence and facilitates your interviews.

Get Started Now