Here is what happens when you try to fetch data directly from the body of a functional component in React 👇
Why does this happen and what tools does React offer to solve this problem?
If your React component affects anything outside of itself, it’s called a side effect.
Side effects shouldn’t happen during component render. Therefore they do not belong to the body of a functional component. React has a special place for them.
To learn more about side effects and why they need a special treatment, check out this brilliant section in the new React documentation - Keeping Components Pure.
Dealing with side effects
The special place for side effects is inside the
useEffect hook. Hence the name.
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.
Let’s try it with our initial component:
useEffect does not run during the render. It runs after the render, which is what we want. But we still have the same problem. That’s because, by default,
useEffect will run after every component render.
Running effects conditionally
There is a way to run effects conditionally, not after every render. The
useEffect hook accepts the dependency list as a second argument. React will only re-run the effect if any dependency in the list changes. Let’s try it out:
When you pass an empty array as a dependency list, the effect will run only once, after the first render. It prevents the infinite loop from happening in our case. However, you might notice that our fetch function relies on the
Reacting to changes
Let’s pick up where we left off and see what happens when we change the component’s props.
We would expect the component to react to prop change and fetch another product, but nothing happens. That’s because we have an empty dependency list.
If the side effect relies on any props or state variables, we should put them in the dependency list. After every render, React will check whether any dependency has changed, and if it did, will re-run the effect.