Skip to content

Commit 86c5795

Browse files
committed
useEffect() explained
1 parent be29f9e commit 86c5795

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

React/hooks-useEffect-api-call.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
Example - Fetching Hacker News hits data - The App component shows a list of items (hits = Hacker News articles). The state and state update function come from the state hook called useState that is responsible to manage the local state for the data that we are going to fetch for the App component. The initial state is an empty list of hits in an object that represents the data. No one is setting any state for this data yet.
2+
3+
```js
4+
import React, { useState, useEffect } from "react";
5+
import axios from "axios";
6+
7+
function App() {
8+
const [data, setData] = useState({ hits: [] });
9+
10+
useEffect(async () => {
11+
const result = await axios(
12+
"http://hn.algolia.com/api/v1/search?query=redux"
13+
);
14+
15+
setData(result.data);
16+
}, []);
17+
18+
return (
19+
<ul>
20+
{data.hits.map(item => (
21+
<li key={item.objectID}>
22+
<a href={item.url}>{item.title}</a>
23+
</li>
24+
))}
25+
</ul>
26+
);
27+
}
28+
29+
export default App;
30+
```
31+
32+
The effect hook called useEffect is used to fetch the data with axios from the API and to set the data in the local state of the component with the state hook’s update function. The promise resolving happens with async/await.
33+
34+
However, when you run your application, you should stumble into a nasty loop. The effect hook runs when the component mounts but also when the component updates. Because we are setting the state after every data fetch, the component updates and the effect runs again. It fetches the data again and again. That’s a bug and needs to be avoided. We only want to fetch data when the component mounts. That’s why you can provide an empty array as second argument to the effect hook to avoid activating it on component updates but only for the mounting of the component.
35+
36+
The second argument can be used to define all the variables (allocated in this array) on which the hook depends. If one of the variables changes, the hook runs again. If the array with the variables is empty, the hook doesn’t run when updating the component at all, because it doesn’t have to watch any variables.
37+
38+
There is one last catch. In the code, we are using async/await to fetch data from a third-party API. According to the documentation every function annotated with async returns an implicit promise: “The async function declaration defines an asynchronous function, which returns an AsyncFunction object. An asynchronous function is a function which operates asynchronously via the event loop, using an implicit Promise to return its result. “. However, an effect hook should return nothing or a clean up function. That’s why you may see the following warning in your developer console log: 07:41:22.910 index.js:1452 Warning: useEffect function must return a cleanup function or nothing. Promises and useEffect(async () => …) are not supported, but you can call an async function inside an effect.. That’s why using async directly in the useEffect function isn’t allowed. Let’s implement a workaround for it, by using the async function inside the effect.
39+
40+
```js
41+
import React, { useState, useEffect } from "react";
42+
import axios from "axios";
43+
44+
function App() {
45+
const [data, setData] = useState({ hits: [] });
46+
47+
useEffect(() => {
48+
const fetchData = async () => {
49+
const result = await axios(
50+
"http://hn.algolia.com/api/v1/search?query=redux"
51+
);
52+
53+
setData(result.data);
54+
};
55+
56+
fetchData();
57+
}, []);
58+
59+
return (
60+
<ul>
61+
{data.hits.map(item => (
62+
<li key={item.objectID}>
63+
<a href={item.url}>{item.title}</a>
64+
</li>
65+
))}
66+
</ul>
67+
);
68+
}
69+
70+
export default App;
71+
```
72+
73+
[Source](https://www.robinwieruch.de/react-hooks-fetch-data/)

React/hooks-basics.md renamed to React/hooks-useEffect.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ function Example() {
7272
}
7373
```
7474

75+
The state and state update function come from the state hook called useState
76+
7577
**What does `useEffect` do?** By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we'll refer to it as our "effect"), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative API.
7678
**Why is `useEffect` called inside a component?** Placing `useEffect` inside the component lets us access the `count` state variable (or any props) right from the effect. We don't need a special API to read it -- it's already in the function scope. Hooks embrace JavaScript closures and avoid introducing React-specific APIs where JavaScript already provides a solution.
7779
**Does `useEffect` run after every render?** Yes! By default, it runs both after the first render _and_ after every update. (We will later talk about [how to customize this](#tip-optimizing-performance-by-skipping-effects).) Instead of thinking in terms of "mounting" and "updating", you might find it easier to think that effects happen "after render". React guarantees the DOM has been updated by the time it runs the effects.

0 commit comments

Comments
 (0)