115 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
---
 | 
						|
tags:
 | 
						|
  - javascript
 | 
						|
  - react
 | 
						|
  - react-hooks
 | 
						|
---
 | 
						|
 | 
						|
# `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'](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]()
 |