Author: M Abo Bakar Aslam

useEffect Hook

YouTube link for Video lecture11:00

Before continuing this lesson, you can download the starting code by using the button below. In the code, you can easily run examples of this lesson.

The useEffect() function is automatically executed when a component completes its rendering. In other words, it runs after the component returns its TSX/JSX.

The useEffect() function takes two parameters:

1. Empty Dependency

When the dependency array is empty ([]), the useEffect() function runs only once after the component is rendered for the first time.

In this case, you can use it for tasks like:

Example 1: Display simple string data in the console window when the App component completes its rendering.

// File: App.tsx located in app-name/src/
 
import { useEffect } from "react";
 
export default function App() {
 
  useEffect(() => {
    console.log("useEffect function is callled");
  }, []); //empty dependency
 
  return (
    <div>
      <h1>useEffect Explanation</h1>
    </div>
  );
}

2. Delay using setTimeout()

The setTimeout() function is used to delay execution of certain code.

It takes two parameters:

This is useful when you want to perform an action after a specific delay.

Example 2: Add some lines in previous example such that that lines will be executed after some delay.

// File: App.tsx located in app-name/src/
 
import { useEffect } from "react";
 
export default function App() {
 
  useEffect(() => {
    console.log("useEffect function is callled");
 
    //delayed execution
    setTimeout(() => {
      console.log("delayed output");
    }, 3000); // 3 seconds delay
  }, []); //empty dependency
  return (
    <div>
      <h1>useEffect Explanation</h1>
    </div>
  );
}

4. Updating State with setTimeout()

You can combine useEffect() with setTimeout() to update state variables after a delay.

In this approach:

This technique is commonly used for:

Example 3: We updated example-code-2 and used useState instead of simple-console.

// File: App.tsx located in app-name/src/
 
import { useEffect, useState } from "react";
 
export default function App() {
 
  const [myState, setmyState] = useState(
    "Are you ready to understand useEffect and setTimeout?"
  );
  useEffect(() => {
    console.log("useEffect function is callled");
 
    //delayed execution
    setTimeout(() => {
      setmyState("Ready");
    }, 5000); // 5 seconds delay
  }, []); //empty dependency
  return (
    <div>
      <h1>useEffect Explanation</h1>
      <br />
      <p>{myState}</p>
    </div>
  );
}

5. Multiple setTimeout() Functions

If you want to perform multiple delayed actions:

Although multiple timers can be used, it is recommended to keep the logic simple and organized.

Example 4: Combine above two example such that multiple setTimeout functions are used. One function is used for simple-console and other is used for state-variable.

// File: App.tsx located in app-name/src/
 
import { useEffect, useState } from "react";
 
export default function App() {
 
  const [myState, setmyState] = useState(
    "we are creating states in useEffect and setTimeOut. Are you ready to understand..."
  );
  useEffect(() => {
    console.log("useEffect function is callled");
 
    //delayed execution
    // 3 seconds
    setTimeout(() => {
      console.log("3 seconds delayed");
    }, 3000);
    // 5 seconds
    setTimeout(() => {
      setmyState("Ready");
    }, 5000); // 5 seconds delay
  }, []); //empty dependency
  return (
    <div>
      <h1>useEffect Explanation</h1>
      <br />
      <p>{myState}</p>
    </div>
  );
}

6. Dependency in useEffect

The dependency array controls when useEffect() runs.

If you include a variable (e.g., a state variable) in the dependency array:

This is useful when:

Example 5: Do following task in this example.

  1. Create a button in TSX
  2. When click on the button, then a function should be called. Display any text in console-window when the function is called.
  3. Define a state named as count and initialize it by 0.
  4. Display value of count in JSX below the button.
  5. Increment the value of count by one whenever the button is clicked (the function is called).
  6. Create useEffect( ) function having dependency on count. Display something when the function is called when value of count is changed.

Solution

// File: App.tsx located in app-name/src/
 
import { useEffect, useState } from "react";
 
export default function App() {
 
  //defining count state
  const [count, setcount] = useState(0);
 
  //defining function for button
  const plusCount = () => {
    console.log("Button is clicked");
    setcount(count + 1);
  };
 
  //useEffect with dependency
  useEffect(() => {
    console.log("called->dependent useEffect");
  }, [count]);
 
  return (
    <div>
      <h1>useEffect Explanation</h1>
      <br />
      <button
        onClick={plusCount}
        style={{ backgroundColor: "red", color: "white", padding: "12px" }}
      >
        Click Me
      </button>
      <p>
        <b>Number of clicks on the button:</b> {count}
      </p>
    </div>
  );
}

7. Multiple useEffect() Functions

You can define more than one useEffect() in a single component.

For example:

This helps in separating logic and improving code readability.

Example 6: We combined above examples such that multiple useEffect( ) functions are used. One is based on dependency and other is with empty dependency.

// File: App.tsx located in app-name/src/
 
import { useEffect, useState } from "react";
 
export default function App() {
 
  const [myState, setmyState] = useState(
    "Are you ready to understand useEffect and setTimeout?"
  );
  //defining count state
  const [count, setcount] = useState(0);
 
  //defining function for button
  const plusCount = () => {
    console.log("Button is clicked");
    setcount(count + 1);
  };
  // useEffect with empty-dependency
  useEffect(() => {
    console.log("useEffect function is callled");
 
    //delayed execution
    // 3 seconds
    setTimeout(() => {
      console.log("3 seconds delayed");
    }, 3000);
    // 5 seconds
    setTimeout(() => {
      setmyState("Ready");
    }, 5000); // 5 seconds delay
  }, []); //empty dependency
 
  //useEffect with dependency
  useEffect(() => {
    console.log("called->dependent useEffect");
  }, [count]);
 
  return (
    <div>
      <h1>useEffect Explanation</h1>
      <br />
      <p>{myState}</p>
      <button
        onClick={plusCount}
        style={{ backgroundColor: "red", color: "white", padding: "12px" }}
      >
        Click Me
      </button>
      <p>
        <b>Number of clicks on the button:</b> {count}
      </p>
    </div>
  );
}

8. Multiple Dependencies in useEffect

You can include multiple variables in the dependency array.

In this case:

This works like an OR condition.

Alternatively, you can:

Example 7: Create a button that will decrement the value whenever click on the button. This example is just like above example but here we added another button and state for decrement.

// File: App.tsx located in app-name/src/
 
import { useEffect, useState } from "react";
 
export default function App() {
 
  //defining count state
  const [count, setcount] = useState(0);
  const [deccountstate, setdeccoutstate] = useState(0);
 
  //defining function for plus button
  const plusCount = () => {
    console.log("plus Button is clicked");
    setcount(count + 1);
  };
 
  //defining function for decrement button
  const decCount = () => {
    console.log("decrement Button is clicked");
    setdeccoutstate(deccountstate - 1);
  };
 
  //useEffect with dependency
  useEffect(() => {
    console.log("called->dependent useEffect");
  }, [count, deccountstate]);
 
  return (
    <div>
      <h1>useEffect Explanation</h1>
      <br />
      <button
        onClick={plusCount}
        style={{
          backgroundColor: "red",
          color: "white",
          padding: "12px",
          marginRight: "8px",
          cursor: "pointer",
        }}
      >
        Increment by 1
      </button>
      <button
        onClick={decCount}
        style={{
          backgroundColor: "red",
          color: "white",
          padding: "12px",
          cursor: "pointer",
        }}
      >
        Decrement By 1
      </button>
      <p>
        <b>Total Plus:</b> {count}
      </p>
      <p>
        <b>Total Decrement:</b> {deccountstate}
      </p>
    </div>
  );
}