useEffect - react hook
Tags: react, javascript
Published: 2021-05-25 07:26:49

Hello guys,

In this article I will explain how does **useEffect** work.

###Prerequisite
Before you dive into the article, it is important you understand what react hooks are. If you are new to react hooks, I will strongly recommend to go through the official documentation. Here is the link([hooks](https://reactjs.org/docs/hooks-intro.html)).

Let's start.

**useEffect** is a react hook which is used to perform side effects(updating DOM, making asynchronous calls...). It basically accepts two arguments.

1. callback function
2. dependencies array(which is optional and it actually decides when the callback function be fired)

Below is the syntax of useEffect.

```javascript
    useEffect(() => {
    
    }, [dependency1, dependency2])
```

Now we can have three scenarios with dependencies array.

**1. No dependency array**
```javascript
    useEffect(() => {
        
    })
```
In this scenario, the callback gets fired **after the initial rendering and everytime any of the component state changes**.

**2. Empty dependency array**
```javascript
    useEffect(() => {
        
    }, [])
```
In this scenario, the callback gets fired **only once after the initial rendering**.

**3. With dependencies**
```javascript
    useEffect(() => {
        
    }, [dependency1, dependency2])
```
In this scenario, the callback gets fired **after the initial rendering and every time any of the dependencies in the dependencies array changes**. 

Let's try to justify above scenarios.

Below I have a component MyApp which basically renders couple of buttons. The first button increments the increment value where as the second button decrements the decrement value.

```javascript
export const MyApp = () => {

  const [increment, setIncrement] = useState(0);
  const [decrement, setDecrement] = useState(0);

  // useEffect 1, 1st scenario
  useEffect(() => {
    console.log(increment, 'without dependency array');
  });
  
  // useEffect 2, 2nd scenario
  useEffect(() => {
    console.log(increment, 'empty dependency array');
  }, [])
  
  // useEffect 3, 3rd scenario
  useEffect(() => {
    console.log(decrement, 'with dependency/ies');
  }, [decrement])

  const incrementCounter = () => {
    setIncrement(increment + 1);
  };

  const decrementCounter = () => {
    setDecrement(decrement - 1);
  };

  return (
    <div>
      <button onClick={incrementCounter}>Increment</button>
      <button onClick={decrementCounter}>Decrement</button>
    </div>
  );
}
```

Also I have 3 **useEffects** describing the 3 scenarios(discussed above).

Now let's try to understand what happens when I click different buttons, what gets logged to console and why.

When the MyApp component is loaded for the first time, we will see 
```
  0 "without dependency array"
  0 "empty dependency array"
  0 "with dependency/ies"
```
logged to the console because we have 3 useEffects and each one is called after the initial rendering.

Now I click the Increment button. What do you think will be logged to console?

```javascript
  1 "without dependency array"
```
What happened here!!!
The increment counter was changed to 1 from 0.That means component state changed. So... 

Callback of **useEffect 1** was fired. Therefore **1 "without dependencies array"** was logged to console.

Callback of **useEffect 2** was not fired because the dependencies array is an empty one.

Callback of **useEffect 3** was not fired because the dependencies array does not include **increment**.

Now I click the Decrement button. What should be logged to console?

```javascript
  1 "without dependency array"
  -1 "with dependency/ies"
```
What happened here!!!
The decrement counter was changed to -1 from 0.That means component state changed. So...

Callback of the **useEffect 1** was fired. Therefore **1 "without dependencies array"** was logged to console.

Callback of **useEffect 2** was not fired because the dependencies array is an empty one.

Callback **useEffect 3** was fired because the **decrement** is in the dependencies array. Therefore **-1 "with dependency/ies"** was logged to console.

###Conclusion
So to conclude, we can say the callback function of the useEffect hook is fired based on how and what we supply into the dependencies array.

That's all for this article. Hope this article was helpful in understanding how the **useEffect** hook behaves based on the dependencies array.

Please leave any feedback, comment or suggestion.