Clue Mediator

How to use useEffect React Hook

📅October 7, 2020

Today we will show you how to use useEffect React Hook. The useEffect is the one of the important hooks that is providing an access to the lifecycle in the functional components.

It is a close replacement for `componentDidMount`, `componentDidUpdate` and `componentWillUnmount`.

In this article, we’ll take several examples to check the lifecycle in the functional component.

useEffect React Hook

  1. Example of the useEffect as componentDidMount
  2. Use the useEffect as componentDidMount and componentDidUpdate
  3. Conditionally run the code using useEffect
  4. Example of the useEffect as componentWillUnmount

1. Example of the useEffect as componentDidMount

Here, we will take a simple example to change the title of the document using useEffect. So first we will show you the same example using the class component.

ClassExample.js

import React, { Component } from "react";

class ClassExample extends Component {
  componentDidMount() {
    document.title = "Class Example: componentDidMount - Clue Mediator";
  }

  render() {
    return (
      <div>
        <span>Class Example: componentDidMount - </span>
        <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">
          Clue Mediator
        </a>
      </div>
    );
  }
}

export default ClassExample;

Let’s convert the above code using useEffect.

HookExample.js

import React, { useEffect } from "react";

const HookExample = () => {
  useEffect(() => {
    document.title = "Hook Example: componentDidMount - Clue Mediator";
  }, []);

  return (
    <div>
      <span>Hook Example: componentDidMount - </span>
      <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">
        Clue Mediator
      </a>
    </div>
  );
};

export default HookExample;

You have to pass an empty array (`[ ]`) to perform the useEffect as componentDidMount.

2. Use the useEffect as componentDidMount and componentDidUpdate

Let’s take another example to use the useEffect as componentDidMount and componentDidUpdate. So here we will use the above example to update the document title with useState hook.

ClassExample.js

import React, { Component } from "react";

class ClassExample extends Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0
    };
  }

  componentDidMount() {
    document.title = `Class Counter: ${this.state.counter} - Clue Mediator`;
  }

  componentDidUpdate() {
    document.title = `Class Counter: ${this.state.counter} - Clue Mediator`;
  }

  render() {
    return (
      <div>
        <div>
          <span>Class Example: componentDidMount & componentDidUpdate - </span>
          <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">
            Clue Mediator
          </a>
        </div>
        <input type="button" value="Counter++" onclick="{()" =="">
            this.setState(prevState => ({ counter: prevState.counter + 1 }))
          }
        />
      </div>
    );
  }
}

export default ClassExample;

Now let’s create the same example using useEffect.

HookExample.js

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

const HookExample = () => {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    document.title = `Hook Counter: ${counter} - Clue Mediator`;
  });

  return (
    <div>
      <div>
        <span>Hook Example: componentDidMount & componentDidUpdate - </span>
        <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">
          Clue Mediator
        </a>
      </div>
      <input type="button" value="Counter++" onclick="{()" ==""> setCounter(prevCounter => prevCounter + 1)}
      />
    </div>
  );
};

export default HookExample;

If you remove the second argument of the useEffect then it will act as componentDidMount and componentDidUpdate.

3. Conditionally run the code using useEffect

If you want to conditionally execute the code using useEffect then we have to use the second argument of the useEffect. For demonstration, we will use an input field for name and button for counter to manage the state variable.

ClassExample.js

import React, { Component } from "react";

class ClassExample extends Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0,
      name: ""
    };
  }

  componentDidMount() {
    document.title = `Class Counter: ${this.state.counter} - Clue Mediator`;
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.counter !== this.state.counter) {
      console.log("componentDidUpdate called!");
      document.title = `Class Counter: ${this.state.counter} - Clue Mediator`;
    }
  }

  render() {
    return (
      <div>
        <div>
          <span>Class Example: - </span>
          <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">
            Clue Mediator
          </a>
        </div>
        <input placeholder="Enter name..." type="text" value={this.state.name} onchange="{e" ==""> this.setState({ name: e.target.value })}
        />
        <br>
        <input type="button" value="Counter++" onclick="{()" =="">
            this.setState(prevState => ({ counter: prevState.counter + 1 }))
          }
        />
      </div>
    );
  }
}

export default ClassExample;

Here we have used the `prevState` in the componentDidUpdate to avoid the unnecessary rendering. Let’s mimic the same example using the useEffect.

HookExample.js

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

const HookExample = () => {
  const [counter, setCounter] = useState(0);
  const [name, setName] = useState("");

  useEffect(() => {
    console.log("useEffect called!");
    document.title = `Hook Counter: ${counter} - Clue Mediator`;
  }, [counter]);

  return (
    <div>
      <div>
        <span>Hook Example: - </span>
        <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">
          Clue Mediator
        </a>
      </div>
      <input placeholder="Enter name..." type="text" value={name} onchange="{e" ==""> setName(e.target.value)}
      />
      <br>
      <input type="button" value="Counter++" onclick="{()" ==""> setCounter(prevCounter => prevCounter + 1)}
      />
    </div>
  );
};

export default HookExample;

Pass the variable (Like `[counter]`) in the array to manage the conditional execution. You can pass the multiple variables in an array such as `[var1, var2, var3]` to re-run the effect even if just one of them is different.

4. Example of the useEffect as componentWillUnmount

Let’s use the `addEventListener` in componentDidMount to capture the mouse coordinates and use the `removeEventListener` in componentWillUnmount for cleanup.

ClassExample.js

import React, { Component } from "react";

class ClassExample extends Component {
  componentDidMount() {
    window.addEventListener("mousemove", this.updateTitle);
  }

  componentWillUnmount() {
    window.removeEventListener("mousemove", this.updateTitle);
  }

  updateTitle = e => {
    document.title = `Mouse Coordinates: ${e.pageX}, ${e.pageY} - Clue Mediator`;
  };

  render() {
    return (
      <div>
        <span>Class Example: componentWillUnmount - </span>
        <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">
          Clue Mediator
        </a>
      </div>
    );
  }
}

export default ClassExample;

Now we will convert the above example in Hooks. If your effect returns a function from `useEffect` Hook, React will run it when it is time to clean up.

HookExample.js

import React, { useEffect } from "react";

const HookExample = () => {
  useEffect(() => {
    const updateTitle = e => {
      document.title = `Mouse Coordinates: ${e.pageX}, ${e.pageY} - Clue Mediator`;
    };

    window.addEventListener("mousemove", updateTitle);

    return () => {
      window.removeEventListener("mousemove", updateTitle);
    };
  }, []);

  return (
    <div>
      <span>Hook Example: componentWillUnmount - </span>
      <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">
        Clue Mediator
      </a>
    </div>
  );
};

export default HookExample;

That’s it for today.
Thank you for reading. Happy Coding..!!