> For the complete documentation index, see [llms.txt](https://dailyjournal.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dailyjournal.gitbook.io/notes/languages/javascript/libraries/react/hooks/useeffect.md).

# useEffect

A Hook that lets you perform side effects in functional components.

Data fetching, setting up a subscription, manually changing the DOM, and the use of time functions such as `setTimeout()` in React components are all examples of side effects (or just “effects”).

{% hint style="info" %}
If you’re familiar with React class lifecycle methods, you can think of `useEffect` Hook as `componentDidMount()`, `componentDidUpdate()`, and `componentWillUnmount()` combined.
{% endhint %}

There are two common kinds of side effects in React components: those that don’t require cleanup, and those that do.

## Effects Without Cleanup

Sometimes, we want to **run some additional code after React has updated the DOM.**&#x20;

Network requests, manual DOM mutations, and logging are common examples of effects that don’t require a cleanup. We say that because we can run them and immediately forget about them.

{% tabs %}
{% tab title="Using Hooks" %}

* Placing `useEffect` inside the component lets us access the `count` state variable (or any props) right from the effect. We don’t need a special API to read it — it’s already in the function scope.
* `useEffect` runs both after the first render *and* after every update.&#x20;

```jsx
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>
  );
}
```

{% endtab %}

{% tab title="Using Classes" %}

* In React class components, the `render` method itself shouldn’t cause side effects. It would be too early — we typically want to perform our effects *after* React has updated the DOM.
* This is why in React classes, we put side effects into `componentDidMount` and `componentDidUpdate`.

```jsx
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>
    );
  }
}
```

{% endtab %}
{% endtabs %}

## Effects With Cleanup

Closing a socket, clearing timers, and setting up a subscription to some external data source are some common examples that do require a cleanup.&#x20;

It is important to clean up so that we don’t introduce a memory leak!

{% tabs %}
{% tab title="Using Hooks" %}

* If your effect returns a function, React will run it when it is time to clean up. This lets us keep the logic for adding and removing subscriptions close to each other. They’re part of the same effect!
* React performs the cleanup when the component unmounts. However, 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.

```jsx
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 () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

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

{% endtab %}

{% tab title="Using Classes" %}

* In a React class, you would typically set up a subscription in `componentDidMount`, and clean it up in `componentWillUnmount`.&#x20;
* For example, let’s say we have a `ChatAPI` module that lets us subscribe to a friend’s online status. Here’s how we might subscribe and display that status using a class:

```jsx
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';
  }
}
```

\
Lifecycle methods force us to split this logic even though conceptually code in both of them is related to the same effect..
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Unlike `componentDidMount()` or `componentDidUpdate()`, effects scheduled with `useEffect` don’t block the browser from updating the screen. This makes your app feel more responsive.
{% endhint %}

#### Skipping effects

By default, the **useEffect** Hook runs after the first render as well as after each update. However, you might need to skip applying an effect in situations like when certain values haven’t changed since the last re-render.

You can easily skip applying effects by passing an array as a second argument to the **useEffect** Hook. As arguments, you can pass props or state values. When an argument is passed, the **useEffect** Hook will be executed after the initial render and only when the argument values change.

Consider the following example, in which the effect is only invoked if the variable count is updated.

```jsx
useEffect(() => {
  console.log(count);
}, [count]);
```

If you want to run and clean up the effect only once, you can pass an empty array (\[]) as the second argument.

#### `useEffect` Hook accepts a callback function that is invoked whenever a render occurs.
