What is useEffect hook and how do you use it?
Tags: react, webdev
Published: 2020-06-29 20:58:27

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dcrfwbag7oq69b25obut.png)

<h1> Content </h1>
<ol>
    <li> <a href = "#introduction"> Introduction </a> </li>
 <li> <a href = "#arguments"> What arguments are passed to useEffect hook? </a> </li>
 <li> <a href = "#effect"> First argument to useEffect </a> </li>
 <li> <a href = "#clean-up"> Return value of effect </a> </li>
 <li> <a href = "#deps"> Second argument to useEffect </a> </li>
 <li> <a href = "#functions"> Passing a function as a dependency </a> </li>
 <li> <a href = "#references"> References </a> </li>
</ol>

This is the third post of my react hooks series. If you haven't looked at the first two, follow the links below to look at them.

<ol>
 <li> <a href = "https://dev.to/nibble0101/what-is-usestate-hook-and-how-do-you-use-it-3d71"> What is useState hook and how do you use it? </a> </li>
  <li> <a href = "https://dev.to/nibble0101/what-is-usereducer-hook-and-how-do-you-use-it-3j83"> What is useReducer hook and how do you use it? </a> </li>
</ol>

<h1 id = "introduction"> Introduction to useEffect hook. </h1>

A hook is a function which enables you use state and other react features without writing ES6 classes.
`useEffect` hook is part of the react hooks API. If you are familiar with react life cycles, `useEffect` hook is equivalent to life cycle methods `componentDidMount`, `componentDidUpdate` and `componentWillUnmount` combined. In fact, according to the [React documentation on Hooks](https://reactjs.org/docs/hooks-effect.html), `useEffect` hook was developed to address some of the challenges posed by life cycle methods of ES6 class components. Since this post is about what effect hook is and how it is used, i won't go into why it was developed. You can look at it [Here](https://reactjs.org/docs/hooks-effect.html).
In React functional components, we perform [`side effects`](https://reactjs.org/docs/hooks-effect.html) such as fetching data from an API or manually updating the DOM inside the `useEffect` hook.

<h1 id = "arguments"> What arguments are passed to useEffect hooks? </h1>

`useEffect` is a function which takes two arguments. The first argument passed to `useEffect` is a function called `effect` (You can guess why this hook is named `useEffect`) and the second argument (which is optional) is an array of dependencies. Below is an illustration of how it is used. 
```javascript
import React, { useEffect } from "react";
import { render } from "react-dom";
const App = props => {
  useEffect(() => {
    console.log("Effect has been called");
  }); //Second argument to useEffect has been omitted
  return <h1> Hello world! </h1>;
};  
const root = document.getElementById("root");
render(<App />, root);
    
```

<h2 id = "effect"> First argument to useEffect </h2>
The first argument, called `effect`, is a function which either returns a function (called `cleanup`) or `undefined`. `effect` is executed when the component is mounted (on first render) and whether it is executed in subsequent updates is determined by the  array of dependencies passed as the second argument.

<h3 id = "clean-up"> Return value of effect argument </h3>

From the <a href = "#effect"> Previous section </a>, we said the first argument to `useEffect` is a function called `effect`. `effect` takes no parameters and it MUST return either a function or undefined. If it returns a function, then the function returned is called `cleanup`. `cleanup` is executed before calling `effect` (to clean up effects from previous render). If you are curious about why and when cleanup is necessary, look at an explanation in the [React documentation](https://reactjs.org/docs/hooks-effect.html). Since `effect` returns either a function or undefined, it is not uncommon to see `effects` without `cleanup`.

<h2 id = "deps"> Second argument to useEffect </h2>

The second argument to `useEffect` is an array of <a href = "#deps"> dependencies </a>. If you want to control when `effect` is to be executed after mounting the component, then pass an array of dependencies as the second argument. `dependencies` are values defined outside `useEffect` but are being used inside `useEffect` like:
```javascript
     function App(){
         const[state, setState] = useState(0);
          // state is defined here
         useEffect(() => {
              console.log(state); 
              //value of state is used here therefore must be passed as a dependency
         }, [state])
         
     }
```
React compares the current value of dependency and the value on previous render. If they are not the same, `effect` is invoked.
This argument is optional. If you omit it, `effect` will be executed after every render. If you want `effect` to be executed only on first render, you can pass an empty array.

```javascript
     useEffect(() => {
       console.log("Effect has been called");
}, []) // Empty array as dependency, useEffect is invoked once
```
Dependencies can be state or props. It should be noted that any value defined outside `useEffect` but inside the component, has to be passed as a dependency if you are to use it inside `useEffect`. This is illustrated below.

```javascript
  function App(props) {
     const [count, setCount] = React.useState(1);
     // count and setCount are defined inside component(App) but outside useEffect
     useEffect(() => {
       //count is being used inside useEffect. Therefore must be passed as dependency.
       console.log(count);
}, [count])
}
```

<h1 id = "functions"> Passing a function as a dependency </h1>

You might be wondering if you define a function outside `useEffect` and invoke it inside `effect`, do you need to pass it as a dependency? 
For exampe:
```javascript
 function App(props){
    const [data, setData] = useState(null);
    const fetchData = () => {
         //fetch some data 
    }
    useEffect(() => {
    fetchData(); //Invoked inside useEffect
}, [fetchData])

}

```
It is not recommended to define a function outside and invoke it inside `effect`. Above case leads to `fetchData` being invoked on every render because the dependency passed is a function and functions are objects. React will compare `fetchData` for previous and current render and the two will not be the same hence triggering a call to `effect`.

According to [React documentation on useEffect hook](https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies),

> It’s difficult to remember which props or state are used by functions outside of the effect. This is why usually you’ll want to declare functions needed by an effect inside of it. Then it’s easy to see what values from the component scope that effect depends on:

> You can also move the function inside the effect so that it doesn’t need to be in its dependency list.

Thank you for reading this far. This is a brief introduction to `useEffect`. There are lots of things about `useEffect` hook i have not touched in this article. It takes some time getting used to it. If you want to deeply understand `useEffect`, look at the references below. If you find this article useful, share it on [Twitter](https://twitter.com/?lang=en). Someone could find it useful too. If you find anything technically inaccurate please feel free to comment below.

<h1 id = "references"> REFERENCES </h1>

<ul>
    <li> <a href = "React Hooks FAQ"> React Hooks FAQ </a> </li>
    <li> <a href = "https://reactjs.org/docs/hooks-reference.html"> Hooks API Reference </a> </li>
   <li> <a href = "https://overreacted.io/a-complete-guide-to-useeffect"> Complete guide to React</a> </li>
</ul>