React101: The Effect Hook

React provides a lot of tools to aid web development. The top primary tasks could be:
- Work with the DOM/browser to render UI to the page.
- Manage state for us between render cycles (i.e. state values are remembered from one render to the next).
- Keep the UI updated whenever state changes occur.
What can’t React handle on its own?
Outside effects!
- local Storage
- API/database interactions
- subscriptions(e.g. web sockets)
- Syncing 2 different internal states together
React offers “useEffect” hook to manage changes that fall outside React’s preview. The hook allows the developers to synchronize the state with outside systems like storage, user interactions, and more.
Using the Effect Hook
The Effect hook is used to run some JavaScript code after each render to:
- fetch data from a back-end service.
- subscribe to a stream of data.
- manage timers and intervals.
- read from and make changes to the DOM.
Syntax and Default Behavior
The useEffect hook takes in two parameters: a callback function(mandatory) and an array(optional).
In the following example, the fetch call is made outside the React ecosystem and the component will run in an infinite rendering loop, as it keeps logging the data to the console. Also, the hook is executed only after the UI page is rendered.
// side effects
React.useEffect(function() {
console.log("Effect ran")
fetch("https://swapi.dev/api/people/1")
.then(res => res.json())
.then(data => console.log(data))
})
return (
<div>
<pre>{JSON.stringify(starWarsData, null, 2)}</pre>
</div>
)
useEffect Dependencies Array
The dependency array parameter which is optional in the useEffect hook helps React know whether or not it should re-run the effect function. It is optional but is used most of the time. React does not run the effect when the values of the dependencies in the array stay the same between renders.
The codesandbox snippet explains how the callback function behaves differently with different values of the dependency array
Another example of how the dependencies array controls the fetch call made to the Starwars API. The callback function runs every time when the count changes and displays a new result.
useEffect Cleanup function
Some effects require cleanup. When we add event listeners to the DOM, it is important to remove those event listeners once completed to avoid memory leaks.
This is related to the lifecycle of React components. When a component is unmounted, it is recommended any event listener attached to it is removed.
When useEffect function call returns a function, then the useEffect
Hook always treats that as the cleanup function. React will call this cleanup function before the component re-renders or unmounts to clean up each effect call.
Below is a code snippet to count how many times you click on a page. In the absence of a cleanup function, each time the component renders, a new listener is attached to the DOM. Adding a cleanup function removes the last event listener from the DOM.
import React, { useState, useEffect } from 'react';
export default function Counter() {
const [clickCount, setClickCount] = useState(0);
useEffect(() => {
document.addEventListener('mousedown', increment );
return () => {
document.removeEventListener('mousedown', increment)
}
})
// your code here
const increment = () => setClickCount(prevCount => prevCount + 1)
return (
<h1>Document Clicks: {clickCount}</h1>
);
}
A complete example of controlling when effects get called and cleaned up:
import React, { useState, useEffect } from 'react';
export default function Timer() {
const [time, setTime] = useState(0);
const [name, setName] = useState("")
useEffect(() => {
const intervalId = setInterval(() => {
setTime( (prevTime) => prevTime + 1)
},1000)
return () => {
clearInterval(intervalId)
};
}, [])
const handleChange = ({target}) => setName(target.value)
return (
<>
<h1>Time: {time}</h1>
<input type="text" value={name} onChange={handleChange} />
</>
);
}
Review
- Effect refers to a function that we pass as the first argument of the
useEffect()
function. By default, the Effect Hook calls this effect after each render. - The cleanup function is optionally returned by the effect. If the effect does anything that needs to be cleaned up to prevent memory leaks, then the effect returns a cleanup function, then the Effect Hook will call this cleanup function before calling the effect again as well as when the component is being unmounted.
- The dependency array is the optional second argument that the
useEffect()
function can be called with in order to prevent repeatedly calling the effect when this is not needed. This array should consist of all variables that the effect depends on.
The Effect Hook is all about scheduling when the effect’s code gets executed. The dependency array can be used to configure when the effect is called in the following ways:

Hooks give the flexibility to organize the code in different ways, grouping related data as well as separating concerns to keep code simple, error-free, reusable, and testable!
With this, the React101 series comes to an end. I hope you enjoyed reading it.
I made a Tenzies game that uses most of the concepts I penned down.