How does useEffect really work?
Tags: javascript, react, frontend, beginners
Published: 2023-04-12 14:38:14

_In the month of April I’ll publish a small blog series called “Questions from the past”. I’ll be going through my old notebooks from my first year as a developer and answer the questions I think are most important. Today we will discuss the workings of the `useEffect` hook._

`useEffect` is a React Hook that can be both useful and messy at the same time. I know there are already a bunch of blog posts on this, but I want to make it super clear for you when, how and why you can use it. Let's go into it!

You can use `useEffect` to perform various tasks, such as fetching data, updating the DOM, optimising performance or cleaning up resources when the component is unmounted*. 

Let’s take a look at the `useEffect` hook, and analyse bit by bit what it does. To begin, here's the basic code for the `useEffect` hook:

```
useEffect(() => {
// code to run on every render
return () => {
// clean up!
}
  }, [dependencyArray]);
```

### The dependency array
The dependency array is the second parameter of `useEffect`. It’s called literally ‘dependency array’ because this is the array that `useEffect` is dependent on. With that I mean that depending on what's inside the dependency array, your `useEffect` will either run or not run.

There are three things that you can do with the dependency array:

1. Leave it empty.
 `useEffect` will run only once when the component loads for the first time. This is because there are no dependencies that could trigger a re-run of the code.
<pre>
useEffect(() => {
	console.log("The component was loaded for the first time!")
}, []); 
</pre>
- Don’t include it at all. `useEffect` is called on every single state change.
<pre>
useEffect(() => {
   console.log("I ran because there was a state change!")
});
</pre>

3. Put a variable inside the dependencyArray. `useEffect` will run every time that variable changes.
<pre>
const [dogCount, setDogCount] = useState(0);
useEffect(() => {
	console.log(`There are now ${dogCount} dogs!`)
}, [dogCount]);
</pre>

### The return function
The return function (aka the Clean Up function) is called when the component is about the be removed from the screen, or when the `useEffect` needs to cancel the previous effect.

For example, in this code snippet, the `useEffect` will fetch user data every time the value of `userId` changes.

```
const [user, setUser] = useState(null);

useEffect(() => {
  let isRendered = true;

  fetchUserData(userId).then(user => {
    if(isRendered) setUser(user);
  });

  return () => {
    isRendered = false;
  }; 
}, [userId]);
```

When the component is first mounted, it uses the `fetchUserData` function to get the data from the initial `userId`. If the `userId` changes while the component is still showing, the `useEffect` hook makes sure that component only displays the data for the current `userId` and not the old data.

When the `fetchUserData` function returns with the user data, it uses `setUser` to update the component with the new data. This makes sure that the component always shows the correct user data.

So, to sum it up: if you're using React, it's important to know how `useEffect` works, the dependency array, and the return function. I know it can be confusing at first, but once you get the hang of it, it can really help make your React app better and faster. 

_*Component mounting is when React creates and adds a new component to the page for the first time. It sets up the component's initial state, properties, and children, and assigns it a unique identifier. After it's mounted, it can be updated with new information._