React Hooks Interview Questions

1. What is a React Hook ?

React Hooks enable you to use state and other React features without using class components in functional components. With React 16.8, state and side effects can be managed more concisely and simply.

Learn More

2. What are the problems that React Hooks solves ?

There are several problems that React Hooks solve, such as

  • use of class components when dealing with stateful logic
  • difficulty of reusing stateful logic across components
  • complexity of managing side effects and lifecycles
  • By using hooks, developers can write functional components with more reusable and modular code.

    3. In React, what types of hooks are available ?

    There are several built-in hooks in React, such as

  • useState
  • useEffect
  • useContext
  • useReducer
  • useRef
  • useMemo
  • useCallback
  • In React applications, these hooks address state management, side effects, and context.

    4. How do useState and useReducer differ ?

    UseState hooks provide an easy way to maintain state in functional components. A state value is passed in as an input, and then an array with two elements is returned: the current state value and a function to update it. In contrast, the useReducer hook is better suited to managing complex state logic. Like Redux, it takes a reducer function and an initial state, and returns a dispatch function to update the current state.

    useState example

    import React, { useState } from 'react';
    
      const Counter = () => {
        const [count, setCount] = useState(0);
      
        const increment = () => {
          setCount(count + 1);
        };
      
        return (
          <div>
            <p>Count: {count}</p>
            <button onClick={increment}>Increment</button>
          </div>
        );
      }; 

    useReducer example

    import React, { useReducer } from 'react';
    
      const initialState = { count: 0 };
      
      const reducer = (state, action) => {
        switch (action.type) {
          case 'increment':
            return { count: state.count + 1 };
          case 'decrement':
            return { count: state.count - 1 };
          default:
            return state;
        }
      };
      
      const Counter = () => {
        const [state, dispatch] = useReducer(reducer, initialState);
      
        const increment = () => {
          dispatch({ type: 'increment' });
        };
      
        const decrement = () => {
          dispatch({ type: 'decrement' });
        };
      
        return (
          <div>
            <p>Count: {state.count}</p>
            <button onClick={increment}>Increment</button>
            <button onClick={decrement}>Decrement</button>
          </div>
        );
      }; 

    5. What is the process for creating a custom hook in React ?

    React lets you create custom hooks by extracting reusable stateful logic into a separate function and prefixing it with "use". These hooks can be used by other built-in hooks as well as custom hooks. You can use them to encapsulate and share common logic between multiple application components.

    Example of creating a custom hook

    import { useState, useEffect } from 'react';
    
    function useFetch(url) {
      const [data, setData] = useState(null);
      const [loading, setLoading] = useState(true);
    
      useEffect(() => {
        const fetchData = async () => {
          try {
            const response = await fetch(url);
            const json = await response.json();
            setData(json);
            setLoading(false);
          } catch (error) {
            console.error('Error fetching data:', error);
          }
        };
    
        fetchData();
      }, [url]);
    
      return { data, loading };
    } 
    
    // Another Component
    import React from 'react';
    import useFetch from './useFetch';
    
    function MyComponent() {
      const { data, loading } = useFetch('https://api.example.com/data');
    
      if (loading) {
        return <div>Loading...</div>;
      }
    
      return (
        <div>
          <h1>Data:</h1>
          <pre>{JSON.stringify(data, null, 2)}</pre>
        </div>
      );
    } 
    Learn More

    6. Is there a rule for using hooks in React ?

    React hooks must follow three important rules:

  • In order for hooks to be called, they must be called at the top level of a functional component or inside another hook.
  • React function components should call hooks, not JavaScript functions or conditionals.
  • All renders of a component must have the same order of hooks.
  • 7. What is the best way to handle side effects in React Hooks ?

    React Hooks use the useEffect hook to handle side effects. It can be used for obtaining data from an API, subscribing to events, and manipulating DOM elements. In useEffect, the first parameter is a callback function that specifies what should happen when the component renders or when certain dependencies change.

    // Example 
    useEffect(() => {
        // Side effect code goes here
        return () => {
          // Cleanup code goes here (optional)
        };
      }, [dependencies]);  
    Learn More

    8. What is the purpose of the useEffect hook ?

    A useEffect hook is used in functional components to perform side effects. In class components, it combines the functionality of componentDidMount, componentDidUpdate, and componentWillUnmount. You can handle asynchronous actions, interact with external APIs, and update the DOM after a component has rendered using useEffect.

     // Example - Fetching data using useEffect
      import React, { useEffect, useState } from 'react';
    
      const MyComponent = () => {
        const [data, setData] = useState([]);
      
        useEffect(() => {
          const fetchData = async () => {
            const response = await fetch('https://api.example.com/data');
            const result = await response.json();
            setData(result);
          };
      
          fetchData();
        }, []);
      
        return (
          <div>
            {data.map(item => (
              <p key={item.id}>{item.name}</p>
            ))}
          </div>
        );
      }; 
    Learn More

    9. Explain the useEffect hooks dependency array.

    UseEffect hooks accept an optional dependency array as a second argument. You can specify the dependencies that the effect relies on. The effect will run again if any of the dependencies change. An empty dependency array will only run the effect once after initial rendering. It facilitates performance optimization by preventing unnecessary re-renders.

    import React, { useState, useEffect } from 'react';
    
      const ExampleComponent = () => {
        const [count, setCount] = useState(0);
      
        useEffect(() => {
          console.log('Effect triggered!');
          document.title = {count};
        }, [count]);
      
        const increment = () => {
          setCount(prevCount => prevCount + 1);
        };
      
        return (
          <div>
            <p>Count: {count}</p>
            <button onClick={increment}>Increment</button>
          </div>
        );
      };
      
      export default ExampleComponent; 

    10. When should you use the useCallback hook ?

    UseCallback hooks are used to memoize React functions. The memoized callback function is only changed if one of the dependencies changes. It can be useful to optimize performance when passing callbacks as props since it prevents the re-rendering of child components.

    import React, { useState, useCallback } from 'react';
    
      const ExampleComponent = () => {
        const [count, setCount] = useState(0);
      
        // Define the callback function using useCallback
        const handleClick = useCallback(() => {
          setCount(prevCount => prevCount + 1);
        }, []);
      
        return (
          <div>
            <p>Count: {count}</p>
            <button onClick={handleClick}>Increment</button>
          </div>
        );
      };
      
      export default ExampleComponent; 
    Learn More

    11. When should you use the useMemo hook ?

    In React, the useMemo hook is used to memoize expensive computations. The function takes two arguments: a dependency array and a function. Whenever one of the variables changes, the function is re-evaluated. UseMemo is useful when you need to avoid calling a computation-intensive function every time you render.

    import React, { useMemo } from 'react';
    
      function ExampleComponent({ value1, value2 }) {
        const result = useMemo(() => {
          // Perform a computationally intensive calculation
          let sum = 0;
          for (let i = 1; i <= value1; i++) {
            sum += i;
          }
          return sum * value2;
        }, [value1, value2]);
      
        return <div>Result: {result}</div>;
      } 
    Based on value1 and value2, a computationally intensive calculation is performed to compute the result. Value1 and value2 are calculated only when the value changes.
    Learn More

    12. How does the useContext hook work ?

    You use the useContext hook to consume values from the React context. Functional components can access context values directly without having to use context consumers. A context object can be used in a component by passing its current value as an argument to useContext.

    import React, { useContext } from 'react';
    
      // Create a Context
      const MyContext = React.createContext();
      
      // Create a parent component that provides the Context value
      const ParentComponent = () => {
        const data = 'Hello, useContext!';
      
        return (
          <MyContext.Provider value={data}>
            <MyComponent />
          </MyContext.Provider>
        );
      };
      
      // Create a component that consumes the Context
      const MyComponent = () => {
        // Use the useContext hook to consume the Context
        const contextData = useContext(MyContext);
      
        return (
          <div>
            <h1>{contextData}</h1>
          </div>
        );
      };
      
      // Render the ParentComponent
      ReactDOM.render(<ParentComponent />, document.getElementById('root')); 
    Learn More

    13. What are some ways to optimize React Hooks performance ?

    When using React Hooks, you can optimize performance by:

  • You can memoize expensive computations using the useMemo hook.
  • You can memoize functions passed as props by using the useCallback hook.
  • To control when an effect runs, use the dependency array in useEffect.
  • To control when an effect runs, use the dependency array in useEffect.
  • You can memoize the rendering of components by using the React.memo component.
  • 14. What is the purpose of the useRef hook ?

    UseRef creates mutable references that persist across components renders. It gives you access to the underlying DOM element or allows you to store mutable values without re-rendering. For example, useRef is commonly used for accessing DOM elements, managing focus, or storing previous values to compare with the current ones.

    import React, { useRef } from 'react';
    
      function ExampleComponent() {
        const inputRef = useRef(null);
      
        const handleClick = () => {
          // Accessing the input element using the ref
          inputRef.current.focus();
        };
      
        return (
          <div>
            <input type="text" ref={inputRef} />
            <button onClick={handleClick}>Focus Input</button>
          </div>
        );
      } 
    Learn More

    15. When should you use the useReducer hook ?

    In state management, the useReducer hook is an alternative to useState. As arguments, it takes a reducer function and an initial state value and returns the current state along with a dispatch function. Reducers can be useful for state transitions that rely on previous states or for state logic that becomes too complex for useState.

    import React, { useReducer } from 'react';
    
      const initialState = 0;
      
      const reducer = (state, action) => {
        switch (action.type) {
          case 'increment':
            return state + 1;
          case 'decrement':
            return state - 1;
          case 'reset':
            return initialState;
          default:
            return state;
        }
      };
      
      const Counter = () => {
        const [count, dispatch] = useReducer(reducer, initialState);
      
        return (
          <div>
            <p>Count: {count}</p>
            <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
            <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
            <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
          </div>
        );
      };
      
      export default Counter; 
    Learn More

    16. What is the difference between class components and functional components with hooks ?

    A class component is based on an ES6 class and manages state and side effects through a lifecycle method. JavaScript functional components with hooks manage state and side effects through hooks such as useState, useEffect, and others. In addition to encouraging code reuse, hooks provide a more concise and flexible way to manage state.

    17. What is the best way to test components that use hooks ?

    A testing framework such as Jest or React Testing Library can be used to test components that use hooks. By simulating user interactions, mocking API calls, and asserting that the component behaves as expected, you can verify the components behavior. It is possible to test hooks by making sure that state updates accurately, side effects are triggered correctly, and that they render the expected output.

    18. Which are the best practices for using React Hooks ?

    Here are some best practices for using React Hooks:

  • Make sure hooks are called at the top level of functional components.
  • Create custom hooks from reusable logic.
  • Make sure that each render uses the same order of hooks.
  • When creating custom hooks, give them meaningful names.
  • In useEffect, use the dependency array to determine when the effect will run.
  • Split state into multiple useState hooks to prevent unnecessary re-renders.
  • Maintain a concise hook structure and keep it focused on specific tasks.
  • 19. When would you use `useRef` instead of `useState` ?

    In most cases, you would use useState to track a value that can change over time, which affects your component's rendering. In useState, a pair of values are returned: the current state value and a function to update it. Each time the state is updated, it triggers a re-render of the component.

    In contrast, useRef is used primarily to hold mutable values across component renders without having to re-render. Using it, you can store any value as a mutable reference. The value of a useRef is not re-rendered when it is updated, unlike the value of a useState.

    20. When would you use `usememo` instead of `usecallback` ?

    useMemouseCallback
    If you want to memoize a value, use useMemo.If you want to memoize a function, use useCallback.