The useEffect hook in ReactJS
Tags: javascript, react
Published: 2022-07-28 11:56:03

## Introduction
So, when I was a kid, my mama told me
"The new React hooks API is really cool, the `useEffect` hook replaced `componentDidMount` & `componentDidUpdate` of the Class API"

I wanted to ask her more about it but she got busy optimizing her React component that was re-rendering multiple times.

When I got older, I learned more about React & these hooks API, and today I'll try explaining to YOU what my mom didn't explain to ME & Probably your mom didn't too — **`useEffect`**

## Setup
So, here I created a React app in *codesandbox* on my browser

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659006078804/PICp8H_WM.png" align="left" />

**Yup! My Web browser!**

Here's the [link](https://codesandbox.io/s/cranky-mcclintock-l5he9q), interact with it yourself!

For those of you lazy folks who don't wanna go anywhere, here's the code 🫠
```javascript
// App.js

import { useEffect, useState } from "react";

export default function App() {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    console.log(counter);
  });

  return (
    <div style={{ width: "100%", textAlign: "center" }}>
      <h3>{counter}</h3>
      <button onClick={() => setCounter((prevValue) => prevValue + 1)}>
        Increment
      </button>
    </div>
  );
}

```

Simple? huh...

Only 1 state variable defined `counter` which is being incremented at every button tap by `setCounter`, also a `useEffect` with `console.log(counter)` in its function body, nothing kubernetes!

## Code
Let's now focus on the `useEffect` defined here

```javascript
useEffect(() => {
  console.log(counter);
});
```

As evident, by the code, the hook takes a function which it'll internally call at "times". Those "times" can be the component re-render, initial component mount or any state update call which causes the component to, of course, re-render.

After running this code, I tap on the increment button 3 times & these are the console logs I get:

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658992237044/IOOXLZTEg.png" align="left" />

🤔 Hmm... looks like, this particular `useEffect` ran on these occasions:
1. When the component is first mounted ( printed "0" to the console )
2. When I tap the increment button or in short, the state update occurred

Now, lets change the `useEffect` to this:
```javascript
useEffect(() => {
  console.log(counter);
}, []);
```
Notice that we're now passing an empty array "[]" (also known as ***Dependency Array***) as the second argument to the `useEffect` hook

Running the code again, I tap on the increment button 3 times & these are the console log I get:

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658992644563/wc1nrSXHo.png" align="left" />

Okay, so this time the `useEffect` ran only at the time of mount of the component & NOT at the time of state update... INTERESTING! 🧐
<img src="https://media.giphy.com/media/RhPvGbWK78A0/giphy.gif" />

Now, again! let us edit the code once more, bear with me :)

```javascript
//App.js

import { useEffect, useState } from "react";

export default function App() {

  const [counter, setCounter] = useState(0);
  const [anotherCounter, setAnotherCounter] = useState(0)

  useEffect(() => {
    console.log("COUNTER VALUE", counter);
  }, [counter]);

  return (
    <div style={{ width: "100%", textAlign: "center" }}>

      <h3>{counter}</h3>
      <button onClick={() => setCounter((prevValue) => prevValue + 1)}>
        Increment
      </button>

      <br /><br />

      <h3>{anotherCounter}</h3>
      <button onClick={() => setAnotherCounter((prevValue) => prevValue + 1)}>
        Random State Update
      </button>

    </div>
  );
}

```
Alright, so... I've done 3 things here:
1. Add the `counter` state variable to the previously left empty array
2. Add another state variable & called it `anotherCounter`
3. Add the JSX to display & increment the `anotherCounter` variable

I'll now run the app & click on the "Increment" button 3 times & "Random State Update" button 2 times and these are the console logs I got

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658993740296/cfnHngUBa.png" align="left" />

Oohoo! so now the `useEffect` hook is firing our function SELECTIVELY when the `counter` state is changed and not when `anotherCounter` state is changed, although, the `setAnotherCounter` is causing the component to re-render & update the `anotherCounter` to the UI.

Now, you've probably understood to some extent what that "empty array ( [] )" meant...

NICE!

Let us recap what `useEffect` when correctly written can do!

1. With the dependency array left empty, the `useEffect` will run the callback function (defined by us) ONLY ONCE *right after the component renders UI*. (equivalent to `componentDidMount` in class components)
```javascript
useEffect(() => {
  /*
    Here, state initialization logic can be added
    OR, fetch requests to Backend servers can be made for data-fetching
    As this is only running once, you're not bombarding your server
    
  */
}, [])
```
2. With state variable(s) given in the dependency array, the `useEffect` will run when the component first mounts & will also be running whenever the given state variables are changed
```javascript
useEffect(() => {
    // ...
}, [...dependencies])
```
3. With no dependency array defined as its second argument, the hook will call our function on EVERY SUBSEQUENT component re-render
```javascript
useEffect(() => {
  // I don't prefer this but yeah! it's there if you want to use it!
})
```

---

Aaaand... that's a wrap!
Like this post, if you liked it 🙃<br>
But if you loved it? man you gotta follow me on [Twitter](https://twitter.com/bhardwajkuvam) 😉

Feedback is much appreciated! 🤗

---

![](https://media.giphy.com/media/Sgp8NT3adL5eM/giphy.gif)
Meet you another day with another post ⚡️