React Usestate And Useeffect Hooks Complete Guide

 Last Update:2025-06-22T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    7 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of React useState and useEffect Hooks

React useState and useEffect Hooks: Detailed Explanation and Important Information

1. useState Hook

The useState hook is used to add state management to functional components. Prior to hooks, you would need to write class components to hold state, but useState simplifies this process by allowing state to be used in functional components as well.

Syntax:

const [stateVariable, setStateFunction] = useState(initialState);
  • stateVariable: Holds the current value of the state.
  • setStateFunction: A function used to update the state.
  • initialState: The initial value of the state.

Example:

import React, { 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>
    );
}

In the above example, useState is used to create a count state variable initialized to 0. The component renders a button that, when clicked, increments the count by one.

2. useEffect Hook

The useEffect hook lets you perform side effects in functional components. Common side effects include subscriptions, timers, data fetching, and manual DOM alterations. Importantly, useEffect also handles cleanup when a component is unmounted.

Syntax:

useEffect(effect, dependencies);
  • effect: A function that contains code for the side effect.
  • dependencies: An array of values that the effect depends on. If any value changes, the effect will run again.

Example:

import React, { useState, useEffect } from 'react';

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

    useEffect(() => {
        // Fetching data from an API
        fetch('https://jsonplaceholder.typicode.com/todos/1')
            .then(response => response.json())
            .then(json => setData(json));

        // Cleanup function
        return () => {
            console.log('Cleanup');
        };
    }, []); // Empty dependency array means this effect runs once after the initial render

    return (
        <div>
            {data ? (
                <div>
                    <h1>Title: {data.title}</h1>
                    <p>ID: {data.id}</p>
                </div>
            ) : (
                <p>Loading...</p>
            )}
        </div>
    );
}

In this example, useEffect is used to fetch data from an API and store it in the data state variable. The effect is set up with an empty dependency array, so it runs only once after the component mounts. The cleanup function logs a message when the component unmounts.

Important Information

  • State Updates are Asynchronous: Similar to class components, state updates using useState are asynchronous. React may batch multiple state updates together to improve performance.

  • Dependencies Array in useEffect:

    • No Dependencies: If you omit the second argument, the effect runs after every render.
    • Empty Dependencies ([]): With an empty array, the effect runs only once after the initial render.
    • Specific Dependencies: The effect will run every time one of the dependencies changes.
  • Cleanup Function: The optional function returned from useEffect is used for cleanup activities. This is important to avoid memory leaks, especially when setting up subscriptions or adding event listeners.

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement React useState and useEffect Hooks

Step 1: Setting Up Your React Environment

First, make sure you have Node.js installed on your machine. Then, you can create a new React app using Create React App:

npx create-react-app react-hooks-example
cd react-hooks-example
npm start

This command creates a new React project and starts the development server.

Step 2: Create a Simple Counter Component

We'll create a simple counter that increments a count each time a button is clicked.

File: src/Counter.js

import React, { useState } from 'react';

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

  const handleIncrement = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <h1>Counter: {count}</h1>
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
};

export default Counter;

Step 3: Integrate the Counter Component into App.js

File: src/App.js

import React from 'react';
import Counter from './Counter';

function App() {
  return (
    <div className="App">
      <h1>React useState Example</h1>
      <Counter />
    </div>
  );
}

export default App;

Step 4: Adding useEffect to Log the Counter Value to the Console

Now, let's add a useEffect hook to log the count value to the console every time the count changes.

File: src/Counter.js

import React, { useState, useEffect } from 'react';

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

  const handleIncrement = () => {
    setCount(count + 1);
  };

  useEffect(() => {
    console.log('Count changed:', count);
  }, [count]); // Dependency array

  return (
    <div>
      <h1>Counter: {count}</h1>
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
};

export default Counter;

Step 5: Add Another Effect that Runs Only Once on Mount

Let's add another useEffect that runs only once when the component mounts. This is done by passing an empty dependency array.

File: src/Counter.js

import React, { useState, useEffect } from 'react';

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

  const handleIncrement = () => {
    setCount(count + 1);
  };

  useEffect(() => {
    console.log('Component mounted');
  }, []); // Empty dependency array means this effect runs only once

  useEffect(() => {
    console.log('Count changed:', count);
  }, [count]); // This effect runs whenever count changes

  return (
    <div>
      <h1>Counter: {count}</h1>
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
};

export default Counter;

Step 6: Cleanup Effect on Unmount

Now, let's add a cleanup function within one of our useEffect hooks to demonstrate how to clean up resources when the component unmounts.

File: src/Counter.js

import React, { useState, useEffect } from 'react';

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

  const handleIncrement = () => {
    setCount(count + 1);
  };

  useEffect(() => {
    console.log('Component mounted');
    return () => {
      console.log('Component unmounted');
    };
  }, []); // Empty dependency array means this effect runs only once

  useEffect(() => {
    console.log('Count changed:', count);
  }, [count]); // This effect runs whenever count changes

  return (
    <div>
      <h1>Counter: {count}</h1>
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
};

export default Counter;

Explanation:

  • useState: Manages the component's state. In this example, useState is used to track the count value.
  • useEffect: Used for side effects, such as updating the console log when the count changes. The dependency array determines when the effect runs:
    • An empty dependency array [] makes the effect run only once when the component mounts.
    • Passing a value in the dependency array [count] makes the effect run whenever the count changes.
    • Returning a cleanup function from useEffect ensures any side effects are cleaned up when the component unmounts.

Step 7: Test Your Application

Now, you can test your application by running:

npm start

Open your browser and navigate to http://localhost:3000. You should see the counter, and you can click the "Increment" button to see how the count updates and how the console log changes accordingly.

Top 10 Interview Questions & Answers on React useState and useEffect Hooks

1. What are the useState and useEffect hooks in React?

Answer: useState is a hook used for adding state to functional components in React. It returns an array with the current state and a function to update it. On the other hand, useEffect is a hook used for handling side effects in functional components, such as data fetching, subscriptions, or manually changing the DOM. It serves as a combination of componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods from class components.

2. How do you initialize state with useState in a functional component?

Answer: You initialize state by calling useState with an initial value inside a functional component. useState returns an array where the first element is the current state value, and the second element is a function to update it. For example:

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // 0 is the initial state.
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

3. Can you update state based on the previous state in useState?

Answer: Yes, you can update state based on the previous state by passing a function to the state updater function returned by useState. This ensures that the state updates are based on the most recent state. Example:

import React, { useState } from 'react';

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

  function incrementFive() {
    setCount(prevCount => prevCount + 5);
  }

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={incrementFive}>
        Click me
      </button>
    </div>
  );
}

4. What is the purpose of useEffect in React?

Answer: The useEffect hook allows you to perform side effects in functional components. Side effects include fetching data, setting up subscriptions, or manually changing the DOM. The basic syntax is useEffect(effect, dependencies), where effect is the function you want to run, and dependencies are an array of values that the effect depends on. If the dependencies array is empty, the effect runs only once after the initial render.

5. How can you prevent useEffect from running on every render?

Answer: You can control when useEffect runs by specifying dependencies in the dependency array. If the array is empty, the effect runs only once when the component mounts and after unmounting. If you include specific variables in the dependency array, the effect will only run when those variables change. Example:

import React, { useState, useEffect } from 'react';

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

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

    return () => clearInterval(interval); // Cleanup function
  }, []); // Empty dependency array means this effect runs only once

  return <div>Seconds: {seconds}</div>;
}

6. What is the cleanup function in useEffect?

Answer: The cleanup function is an optional return value from the useEffect hook. It’s used to clean up any side effects before the component is removed from the DOM, such as unsubscribing from an event or clearing a timer. This is similar to the componentWillUnmount lifecycle method in class components. Example:

useEffect(() => {
  const socket = new WebSocket('ws://example.com');
  
  socket.onopen = () => {
    console.log('WebSocket connection established.');
  };

  return () => {
    socket.close(); // Cleanup function to close the socket
  };
}, []);

7. Can you use multiple useState and useEffect in the same component?

Answer: Yes, you can use multiple useState and useEffect hooks within the same component. Hooks must always be called at the top level of the component and not inside loops, conditions, or nested functions to ensure they are called in the same order every time the component renders. Example:

import React, { useState, useEffect } from 'react';

function UserProfile() {
  const [userName, setUserName] = useState('');
  const [userAge, setUserAge] = useState('');

  useEffect(() => {
    document.title = `User: ${userName}`;
  }, [userName]);

  useEffect(() => {
    console.log(`User is ${userAge} years old.`);
  }, [userAge]);

  return (
    <div>
      <input
        value={userName}
        onChange={e => setUserName(e.target.value)}
        placeholder="Name"
      />
      <input
        value={userAge}
        onChange={e => setUserAge(e.target.value)}
        placeholder="Age"
      />
    </div>
  );
}

8. What happens if you forget to include dependencies in the useEffect array?

Answer: Forgetting to include dependencies in the useEffect array can lead to unexpected behavior, such as stale closures or unnecessary renders. The effect might not re-run when the dependencies change, which could cause your component to show incorrect data or not respond to changes in props/state properly. Always ensure that all values from the component scope used in the effect are included in the dependencies array.

9. When should you not use setState directly in React?

Answer: In functional components using hooks, you should avoid directly setting state in setState if the new state depends on the previous state. Instead, use the functional form of the state updater function (e.g., setState(prevState => newState)) to ensure the state is updated reliably. Additionally, directly setting state can lead to issues in concurrent mode, where the state could be overwritten by subsequent state updates before the component re-renders.

10. Can useEffect be used for optimization in React?

Answer: While useEffect itself is not primarily used for optimization, it can help improve performance by reducing unnecessary computations and minimizing the number of times a component re-renders. By specifying dependencies, you can control when the effect runs, which can prevent unnecessary operations such as data fetching or event subscriptions. Additionally, memoization hooks like useCallback and useMemo can be combined with useEffect to further optimize performance. Example:

You May Like This Related .NET Topic

Login to post a comment.