Manage server state with useEffect hook
Published: 2021-06-04 12:18:49

{% youtube 0ZJgIjIuY7U %} *Video tutorial of this article*

This article will teach the basics of the `useEffect()` hook to make fetch calls to a server.

We will use the fantastic and free API mockup resource called [JsonPlaceholder](https://jsonplaceholder.typicode.com) to practice some network calls.

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

# Pre-requisites
[Promises](https://www.youtube.com/watch?v=RvYYCGs45L4): Explains a way to run code **only** after other code that we don't know when is going to be ready.

**Note:** If you want to use Async & Await, there is a special hook called useCallback, more info in the section: Additional reading.

---

# Intended result
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f66iflyzdwluwxnk363j.png)
Figure 1: Todo list

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vndc4m6liktn5sebey2.png)
Figure 2: App hierarchy chart.

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

--- 

# Anatomy of the useEffect hook
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tkx5n1ujhnqfzju769re.png)
Figure 3: The parameters of the useEffect hook.

The first parameter is a function usually written as an arrow function. Inside the function, you do your network call using  `fetch()`.

The second parameter is an array of state variables. It is used to tell React to re-render the page only when these state variable changes.

If you omit the second parameter, React will enter an infinite loop, crashing the application. Why? Because as we mentioned during the [Introduction to State management](https://dev.to/softwaredevacademy/introduction-to-state-management-and-react-hooks-285j), React refreshes the page each time the state changes. But if we refresh the page, the fetch data will be called again, changing the state, and the page will be refreshed and so on a so forth.

Think about the second parameter as a **brake** to tell React to refresh the page once instead of entering an infinite loop.

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

---

# Getting started
To tackle the complexity we will focus on 3 areas:
1. [General app setup](#guide-app)
1. [useEffect first argument](#guide-first) (function)
1. [useEffect second argument](#guide-first) (array)

```jsx
import { useEffect, useState } from "react";
import TaskItem from "./components/Item";

export default function App() {
  console.log("1 App.jsx created");

  // State
  const [taskData, setTaskData] = useState([]);

  // Method
  useEffect(() => {
    console.log("2 App.jsx useEffect()");

    fetch("https://jsonplaceholder.typicode.com/todos/")
      .then((response) => response.json())
      .then((json) => setTaskData(json));
  }, [setTaskData]);

  // Component
  const TaskList = taskData.map((item) => {
    return <TaskItem key={item.id} prop={item} />;
  });

  return (
    <div className="App">
      <ol>{TaskList}</ol>
    </div>
  );
}
```

**Note:** This is the first exercise we have a `console.log()` inside the code. This is on purpose, so you can open the console and see the exact moment the `App.jsx` component is destroyed and recreated once we have the server's data.

Lets break down the code line by line:

<span id="guide-app">&nbsp;<span/>
### General App:
1. We import the new hook `useEffect` in addition to the `useState` hook.
1. We create a state variable called `taskItemData` as an empty array to hold the todo items fetched from the server.
1. We use the `useEffect()` hook directly without assigning a const or a function.
1. Finally, TaskList is a list of `<TaskItems/>` by using the `taskData` state getter, and we pass to each copy its corresponding item.

<span id="guide-first">&nbsp;<span/>
### useEffect first argument:
Inside `useEffect`, we pass the arrow function. This will be called each time the contents of the App component change. In this case, we want to refresh the page when new data arrives from the server.

Inside the arrow function, a `fetch()` function calls the server. Note that we need to append 2 `then()` statements to: 
  1. To convert our raw data into legible JSON.
  1. To assign this JSON to our `taskData` state using the `setTaskData()` setter.

<span id="guide-second">&nbsp;<span/>
### useEffect second argument:
We put `setTaskData` in the array inside the second argument of the `useEffect` hook. Because we are only calling the setter and not the getter, we don't need to add `taskData.`

If you omit the `[]` entirely, React will enter an infinite loop because each time you set `setTaskData,` the state will change, refresh the page, and when you set the data again, it will refresh over and over.

If you put the `[]` but leave it empty, React will refresh the page 1 time only. This will work for this small example, but on bigger projects, this will stop calling other network calls because you aren't allowing the page to refresh when other pieces of state change. So get used to putting the necessary state getters and setters.

---

# Conclusion
This example taught you the basics of fetching data using the useEffect hook.

You can take a break before moving to the articles intended for the next day, or [click here](https://dev.to/softwaredevacademy/manage-global-state-with-recoil-js-1h6k) to continue your studies.

My recommendation is to practice creating individual projects for each API endpoint that [JSONPlaceholder](https://jsonplaceholder.typicode.com) has. The goal is to get comfortable setting up the useEffect hook and write its 2 arguments without copying and pasting the code.

If you want to see the finished code, open this [link](https://github.com/softwaredevacademy/sda-react-articles) and open the branch server-state.

---

# Additional reading
* [React hooks](https://reactjs.org/docs/hooks-reference.html) documentation: For a detailed explanation of the difference between all the available hooks.
* [useCallback hook](https://www.youtube.com/watch?v=0ZJgIjIuY7U): A short video tutorial to help you organize your useEffect code into smaller separated async functions.

---

# Credits
* Cover: Photo by <a href="https://unsplash.com/@alexxsvch?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Alexey Savchenko</a> on <a href="/s/photos/city-night?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
* Video tutorial: [Learn useEffect In 13 Minutes - React Hooks Explained](https://www.youtube.com/watch?v=0ZJgIjIuY7U&feature=emb_title) by [Web Dev Simplified](https://www.youtube.com/channel/UCFbNIlppjAuEX4znoulh0Cw).