## React Side-Effects
🔹 *from* [[❞ React Fundamentals (R2R)|React Fundamentals (R2R)]]
🔸 *prev* [[❜ Props Handling|Props Handling]], *next* [[❞ React Custom Hooks (advanced)|React Custom Hooks (advanced)]]
### Overview
A "side effect" is anything that affects something outside the scope of the function being executed.
**Data fetching**, **setting up a subscription**, and **manually changing the DOM** in React components, and **pushing a new item onto an array that was passed in as an argument** are all examples of side effects.
There are two types of side-effects: Those that don't require cleanup, and those that do.
Our side-effect will store recent search from the browser's local storage and retrieve it when the component initializes. We can use the local storage to store the `searchTerm` with an identifier whenever a user types into the **HTML input field**.
```js
const App = () => {
...
const handleSearch = (event) => {
setSearchTerm(event.target.value);
localStorage.setItem('search', event.target.value);
};
}
```
If a stored value exists, set the initial state of `searchTerm` to React's `useState` Hook. Otherwise, default to our initial state ("React").
```js
const App = () => {
...
const [searchTerm,setSearchTerm] = React.useState(
localStorage.getItem('search') || 'React'
);
}
```
This is like syncronizing the browser's local storage and React's state. We're initializing with the local storage (or 'React' fallback) and then writing a new value (to *both* the browser's storage and local state) whenever the handler is called from the input field.
The **side-effect** here is that re-using `setSearchTerm` elsewhere in the app, the local storage will not get updated. That means the side-effect needs to be handled some place more central.
By using the `useEffect` Hook, we can trigger the side-effect each time the searchTerm changes.
```js
const App = () => {
// localStorage added as initial state
const [searchTerm, setSearchTerm] = React.useState(
localStorage.getItem('search') || 'React'
);
// localStorage.setItem in seperated into useEffect Hook
// localStorage set on Event
React.useEffect(() => {
localStorage.setItem('search', searchTerm);
}, [searchTerm]);
// searchTerm set on Event
const handleSearch = (event) => {
setSearchTerm(event.target.value);
}
}
```
`useEffect` takes two arguments:
- first is **function that runs our side effect**
- second is a **dependency array of variables** (`[searchTerm]`). Leaving it blank would cause it to update on every render (initial and updates), but leaving the array blank will cause it to only update on the initial render only.
>[!tip]
> If you’re familiar with React class lifecycle methods, you can think of `useEffect` Hook as `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` combined.
>
Now, whenever and wherever the searchTerm state is updated via setSearchTerm, the browser's local storage will always be in sync with it.
### References
1. Wieruch, Robin (2019). *Side-Effects in React*. [Road to React](https://courses.robinwieruch.de/p/the-road-to-learn-react)
2. *Using the Effect Hook* (2022). [React.js Docs](https://reactjs.org/docs/hooks-effect.html)