## 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)