React - useEffect hook - A Quick Guide
Tags: react, javascript, webdev
Published: 2021-11-24 08:08:15

#What is useEffect?
useEffect is a react built-in hook that allows us to run code on the mount, update and unmount stages of our components lifecycle.

The useEffect hook receives two parameters: one function to be executed and an array of dependencies. 

![hook explanation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/04cy4msejjbgfhxrsv43.png)

#Let's see some examples
On my `app.js` I’ve set two input numbers and one button alongside the `Calculator` component. We set the numbers on the inputs and when we click the button the states get updated and the component gets the number via props. Nothing fancy.

```javascript
import { useRef, useState } from "react";
import "./App.css";
import Calculator from "./Calculator";

const App = () => {
  const inputA = useRef(0);
  const inputB = useRef(0);

  const [numbers, setNumbers] = useState({
	numberA: inputA.current.value,
	numberB: inputB.current.value,
  });

  const getTotalHandler = () => {
	setNumbers({
  	numberA: +inputA.current.value,
  	numberB: +inputB.current.value,
	});
  };

  return (
	<>
  	<div className="container">
    	<div>
      	<label>Input A</label>
      	<input type="number" ref={inputA} />
    	</div>
    	<div>
      	<label>Input B</label>
      	<input type="number" ref={inputB} />
    	</div>
    	<button onClick={getTotalHandler}>Calculate</button>
    	<Calculator numberA={numbers.numberA} numberB={numbers.numberB} />
  	</div>
	</>
  );
};

export default App;
```

I have this component called `Calculator` that receives via props `numberA` and `numberB` and returns the sum. 

```javascript
const Calculator = ({ numberA, numberB }) => {
  return <h1>The total is {numberA + numberB}</h1>;
};

export default Calculator;
```
![example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ohpikohvdk90dvoh3484.png)

##Execute useEffect when the component gets mounted

Now I will use `useEffect` to execute a function that logs me when the component it’s mounted. First I import the `useEffect` hook from `react`.

```javascript
import { useEffect } from "react";
```

To implement this hook I have to set a function to be executed and an array of dependencies and then my component looks like this:

```javascript
import { useEffect } from "react";

const Calculator = ({ numberA, numberB }) => {
  useEffect(() => {
	console.log(`First render`);
  }, []);

  return <h1>The total is {numberA + numberB}</h1>;
};

export default Calculator;
``` 

In this case I left my dependency array empty as I just want this code to be executed when it’s rendered for the first time.

Now when I first load my component I see it on my console:
![example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4sczdzwltew1nxmb874.png)

As the dependency array is empty this log will be executed only when the component gets mounted. If I update the `App` component state and update the `Calculator` props this log function will not execute again. Let’s check:

![example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9emjzrh2vsm025n7k9a0.png)

I’ve updated the `numberA` and `numberB` props but the function did not execute. 

##Execute useEffect each time the props gets updated
Now let’s execute a function each time the props get updated. This is useful to perform side effects based on new props for example to retrieve details from an api on the basis of a value received from props. At the end of the post there’s an example with this.

First I add a second useEffect to my previous code. 

```javascript
import { useEffect } from "react";

const Calculator = ({ numberA, numberB }) => {
  useEffect(() => {
	console.log(`First render`);
  }, []);

  useEffect(() => {
	console.log(`This gets executed each time the props are updated`);
  }, [numberA, numberB]);

  return <h1>The total is {numberA + numberB}</h1>;
};

export default Calculator;
```

This time I did not leave my dependencies array empty and I’ve added the numberA and numberB props on it so the useEffect hook knows that each time one of the props gets updated it has to run the function. Let’s check if it works:

![example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3y7tg1fju29rmzw3ab6h.png)

Yes it does. Actually you will see that the first time the component gets mounted both `useEffect` hooks get executed.

##Using useEffect to get data from an API each time the props get updated

Now I will show you how to take advantage of the `useEffect` hook to get data from an API each time the props of our component is updated. 

For this example I’ve created a new component called `Rick` that uses an id received via props to get data from the Rick and Morty public api.

```javascript
import { useState, useEffect } from "react";

const Rick = ({ id }) => {
  const [character, setCharacter] = useState(null);
  const [request, setRequest] = useState(`pendent`);

  useEffect(() => {
	setRequest(`pendent`);

	const getApiResults = (characterId) => {
  	fetch(`https://rickandmortyapi.com/api/character/${characterId}`)
    	.then((response) => response.json())
    	.then((data) => {
      	setCharacter(data);
      	setRequest(`completed`);
    	});
	};

	getApiResults(id);
  }, [id]);

  let content = ``;

  if (request === `completed`) {
	content = (
  	<>
    	<img src={character.image} alt={character.name} />
    	<h1>{character.name}</h1>
  	</>
	);
  }

  return content;
};

export default Rick;
```

From the `app` component I have a button that generates a random number and passes it via props to the `Rick` component. On the first render we just have the button:

![mockup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vwm717cnynvwlphr3ugr.png)

But each time we click a random number it’s generated and passed via props. This triggers the `useEffect` function that gets the belonging Rick and Morty character based on that id:
![gif example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ofcwvoil4dy1o8h5rb11.gif)