07 Side Effects
Effects
In React there are two types of logic in components:
- rendering logic: what to render
- event handlers: what to do when something happens
The rendering logic must be pure (have no side effects), while the event handlers can have side effects.
But what if rendering should cause side effects?
If this is necessary use React effects with useEffect.
Example
In this example, the useEffect hook is used to fetch data from an API on component mount.
import { useState, useEffect } from 'react';
export default function App() {
const [data, setData] = useState(null);
// fetch data on component mount (-> empty dependency array)
useEffect(() => {
fetch('https://catfact.ninja/fact')
.then((response) => response.json())
.then((data) => setData(data));
}, []);
return (
<div>
{data ? (
<div>
<h1>Cat Fact</h1>
<p>{data.fact}</p>
<p><small>Lenght: {data.length}</small></p>
</div>
) : (
<p>Loading...</p>
)}
</div>
);
}
Dependencies
The useEffect hook takes a second argument: the dependency array.
By default, effect would be executed on every render.
This does not make sense in most cases.
The dependency array can be used to specify when the effect should be executed.
It contains all state variables that if changed should trigger the effect to run again.
import { useState, useEffect } from 'react';
export default function App() {
const [data, setData] = useState(null);
const [count, setCount] = useState(0);
// fetch data when count changes
useEffect(() => {
fetch('https://catfact.ninja/fact')
.then((response) => response.json())
.then((data) => setData(data));
}, [count]);
return (
<div>
{data ? (
<div>
<h1>Cat Fact</h1>
<p>{data.fact}</p>
<p><small>Lenght: {data.length}</small></p>
</div>
) : (
<p>Loading...</p>
)}
<button onClick={() => setCount(count + 1)}>Fetch new fact</button>
</div>
);
}
Working with state and effects could lead to infinite loops.
For example, if the effect changes the state variable that triggers the effect, the component is re-rendered, triggering the effect again.
This can be prevented by using a useRef hook or by not updating the state that triggers the effect.
Thinking React
React requires a different way of thinking than traditional web development. In React you first break the UI into components. Then you descibe the different visual states for each component. Finally, you connect the components together so that data can flow through them.
The Thinking in React provides a step by step example.