eolas/neuron/233bf7c7-59e9-471c-8275-895571468b75/React_useEffect.md
2024-11-13 18:22:06 +00:00

114 lines
3.5 KiB
Markdown

---
tags:
- javascript
- react
---
# `useEffect`
`useEffect` should be used for any background process that does not arise as a
result of a user interaction or standard state change. The canonical example
would be dispatching a request to an API to retrieve data to display in a
component's initial render.
`useEffect` enshrines but also simplifies the
[lifecyle methods](Lifecycle_methods.md) that are used with
class-based React components.
## Demonstration
```jsx
const [workflowTitle, setWorkflowTitle] = useState("");
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchWorkflowTitle = () => {
axios
.post(`${process.env.REACT_APP_ENDPOINT}/load-workflows`, {
workflow_id: project_id,
user_id: isAuth?.userId,
})
.then((res) => {
setWorkflowTitle(res?.data?.meta.name);
})
.finally(() => setLoading(false))
.catch((err) => {
console.error(err);
});
};
setLoading(true);
fetchWorkflowTitle();
}, [project_id, isAuth]);
```
In this example we fetch some data from a REST API and store the response value
as state, which can then be accessed within our JSX template.
## Function placement
In the example, the function is declared inside of the `useEffect` hook and then
called. We do this to avoid adding the function to the dependency array, which
we couldn't do if we defined it outside of the hook, somewhere in the component.
If we did this, the function would run on every render by default and would be
recalled again because of its placement in the dependency array, which leads to
the 'too many rerenders' error.
An alternative would be to define it outside of the component itself but this is
difficult since it requires state from the component to run.
## Dependency array
Note the array that is the second argument to `useEffect`. This is the
**dependency array** and is how we manage the lifecycle of the side-effect.
- After the initial call on render, the function within the `useEffect` block
will run any time one of the dependencies update. The dependency array
typically refers to variables that are defined within the hook but can also
contain references to variables outside of it.
- If you do not include the array, the effect runs on every render
- If you pass an empty array, the effect will only run once on the initial
render
## Cleanup functions
The syntax of the `useEffect` hook also allows you to handle cleanup: something
you want to do when the component unmounts (another example of how this hook
recasts the traditional [lifecycle methods](Lifecycle_methods.md))
. In addition to running on unmount, the cleanup function will run before the
effect runs again (i.e. when it runs in response to a change in one of the
elements of the dependency araray). This is chiefly used to prevent
[memory leaks](Memory_leaks.md) and the
['update on unmounted component error'](React_errors.md#state-update-on-unmounted-component).
You do this by having a `return` clause after the main effect. Schematically:
```js
useEffect(() => {
// Run your effect;
return () => {
// Put your cleanup function here
};
}, [input]);
```
Here is an example of using a cleanup to cancel a subscription
```js
useEffect(() => {
let isApiSubscribed = true;
axios.get(API).then((response) => {
if (isApiSubscribed) {
// handle success
}
});
return () => {
isApiSubscribed = false;
};
}, []);
```
## Resources
[Understanding the React useEffect cleanup function]()