How to use the React useEffect Hook
Tags: react, tutorial
Published: 2021-02-14 23:59:14

---
title: How to use the React useEffect Hook
published: true
date: 2021-02-13 00:00:00 UTC
tags: react, tutorial
canonical_url: https://www.mariokandut.com/how-to-use-useeffect-hook-in-react/
---

 **Hooks** are available in React, since v16.8 (2018) and enable **function components** to **manage state** and **side effects**. They work **side-by-side with existing code.** and have a lot of other great features, check out the [Intro to React Hooks](https://www.mariokandut.com/how-to-use-react-hooks/) blog post.

React provides a few **built-in Hooks** like **useState** and **useEffect**. This blog post is about the **useEffect** hook, for more information about the React useState Hook checkout this blog post [How to use the useState hook](https://www.mariokandut.com/how-to-use-react-usestate-hook/).

[💰: Start your cloud journey with $100 in free credits with DigitalOcean!](https://m.do.co/c/29f238135b61)

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#useeffect)useEffect

The Effect Hook lets you perform side effects in function components. Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. They can also be just called effects.

The **useEffect** Hook can be understood as **componentDidMount, componentDidUpdate, and componentWillUnmount combined** in the React class lifecycle methods.

There are two different types of side effects in React components:

- those that don’t require cleanup, and
- those that do.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#effects-without-cleanup)Effects without Cleanup

Some examples of effects that don’t require a cleanup are network requests, manual DOM mutations, and logging. We can run them and immediately forget about them.

Let's have a look on how class components and function components can handle these type of side effects.

The following example is based on the counter example from the [useState hook](https://www.mariokandut.com/how-to-use-react-usestate-hook/) blog post. Let's say we want to update the document title after React updates the DOM:

```
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
  }
  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button
          onClick={() =>
            this.setState({ count: this.state.count + 1 })
          }
        >
          Click me
        </button>
      </div>
    );
  }
}
```

In React classes, side effects are in life cycle states, in this case in componentDidMount and componentDidUpdate. As you can see in the code example above, there is code duplication. In many cases we want to update a component who did just mount or has been updated, basically after every render.

The same use case with using React Hooks:

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

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

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

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

With the useEffect Hook you tell React that your component needs to do something after rendering. React will call the effect after performing DOM updates.

The useEffect Hook is placed inside the component to access the state (count variable) right from the effect, without any additional APIs, it's already in scope.

**Hooks embrace JavaScript closures** and avoid introducing React-specific APIs where JavaScript already provides a solution.

The useEffect hook will run on every render. If you come from React classes, don't think like _mount_ or _unmount_, think of useEffect like _after rendering_.

When you take a detailed look at the useEffect Hook, you will see that the function passed into it changes on every render. This is intentional and, we don't have to worry about count getting stale. Every time we re-render , we schedule a different effect, replacing the previous one.

Effects scheduled with **useEffect** don't block the browser from updating the screen, componentDidMount or componentDidUpdate do.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#effects-with-cleanup)Effects with Cleanup

The other type of effects, are effects which require a cleanup. This could be a subscription to some external data source. If we don't clean up after subscribing we would introduce a memory leak in our application.

The React docs also have a great example for this, which I am going to utilize below. Let’s say we have a ChatAPI module that lets us subscribe to a friend’s online status, and we compare using Classes and using Hooks.

In a **React Class component** , you would typically set up a subscription in `componentDidMount`, and clean it up in `componentWillUnmount`.

```
class FriendStatus extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOnline: null };
    this.handleStatusChange = this.handleStatusChange.bind(this);
  }

  componentDidMount() {
    ChatAPI.subscribeToFriendStatus(
      this.props.friend.id,
      this.handleStatusChange,
    );
  }
  componentWillUnmount() {
    ChatAPI.unsubscribeFromFriendStatus(
      this.props.friend.id,
      this.handleStatusChange,
    );
  }
  handleStatusChange(status) {
    this.setState({
      isOnline: status.isOnline,
    });
  }

  render() {
    if (this.state.isOnline === null) {
      return 'Loading...';
    }
    return this.state.isOnline ? 'Online' : 'Offline';
  }
}
```

The lifecycle methods `componentDidMount` and `componentWillUnmount` need to mirror each other. Lifecycle methods force us to split this logic even though conceptually code in both of them is related to the same effect.

In a React **Function Component** with the **useEffect Hook** the code for adding and removing a subscription is so tightly related that useEffect is designed to keep it together. If your effect returns a function, React will run it when it is time to clean up.

With the useEffect Hook it could be written like this:

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

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(
      props.friend.id,
      handleStatusChange,
    );
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(
        props.friend.id,
        handleStatusChange,
      );
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
```

**Every effect may return a function that cleans up after it**. This lets us keep the logic for adding and removing subscriptions close to each other, and they're just part of the same effect.

React **performs the cleanup when the component unmounts**. However, as we learned earlier, effects run for every render and not just once. This is why **React also cleans up effects from the previous render before running the effects next time**.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#tldr)TL;DR

- The Effect Hook lets you perform side effects in function components.
- There are two different types of useEffect hooks, with cleanup and without.

Thanks for reading and if you have any **questions** , use the **comment** function or **send me a message** **[@mariokandut](https://www.twitter.com/mariokandut)**. If you want to know more about **[React](https://www.mariokandut.com/tags/react)**, have a look at these [React Tutorials](https://www.mariokandut.com/tags/react).

**References (and Big thanks):**

[React Hooks](https://reactjs.org/docs/hooks-intro.html#motivation), [Using the Effect Hook](https://reactjs.org/docs/hooks-effect.html)