The React useEffect hook is one of the most common (and useful) hooks in React. In this guide, I’m going to walk you through understanding and using the useEffect hook in your components.
Prerequisite Knowledge
What are side effects in React?
If you have been programming for a while, you may have heard the term pure function. A pure function is a function that does not have any side effects. Given the same inputs, we expect a pure function to return the same outputs no matter how many times we call it. The diagram below demonstrates this:
Most simple React components are pure functions. For example, the ProductDisplay
component below is a pure function. It will always produce the same output, given the same input.
const ProductDisplay = ({ product }) => {
return <h2>{ product.name }</h2>;
};
This component is simple, predictable, and testable. But some functions have “side effects,” meaning that their output is based on something other than their inputs. For example, imagine if our ProductDisplay
component retrieved its data from a third-party API.
const ProductDisplay = () => {
let product = {};
// This API call is a side effect
fetch('https://someapi.com/endpoint')
.then(res => res.json())
.then(data => product = data);
return <h2>{ product.name }</h2>;
};
This is called a side effect, and it is bad practice to produce side effects this way. This is where the useEffect hook comes in.
What is the useEffect Hook for?
If we want our React component to have a side effect, we can use the useEffect hook. Side effects created with useEffect
only run after the component has rendered, making these effects more predictable.
useEffect
sets up some code to run after the component has rendered. There are three ways to do this, to run this code at different events:
- Run the code each time the component is rendered or re-rendered.
- Run the code only after the first render.
- Run the code after the first render, and then only when certain variables are updated
Using the useEffect Hook
The useEffect
hook takes two parameters:
- The callback function that will run as a side effect.
- (Optional) A “dependency array” that sets the conditions for the effect.
Running an effect on every render
If we do not provide a dependency array, the side effect will run after every re-render of the component.
import { useEffect } from 'react';
const SomeComponent = () => {
useEffect(() => {
console.log('COMPONENT RENDERED!');
});
return <h1>I am a component</h1>
};
Running a side effect on the first render
To make useEffect
only run our callback the first time the component is rendered, provide an empty array as the second parameter.
import { useEffect } from 'react';
const ShowNameAndScreamAtConsole = ({ name }) => {
useEffect(() => {
console.log(name.toUpperCase() + '!!!');
}, []);
return <h1>{ name } </h1>
};
Running a side effect when variables are updated
To keep a watch on certain variables and run some code when they update, pass the watched variables as the dependency array in the call to useEffect
.
import { useEffect, useState } from 'react';
const TextInput = () => {
const [userInput, setUserInput] = useState('');
useEffect(() => {
console.log('Input changed!');
}, [userInput]);
const handleChange = (input) => setUserInput(input);
return <input type='text' onChange={} value={userInput} />;
};
Every time the user types in the text box, a message saying “Input changed!” will be logged to the console, because the userInput
state variable is being watched as part of the useEffect
dependency array.
Conclusion
The React useEffect hook allows you to set up different kinds of side effect for functional components. The number of ways to use it is bound only by your creativity.
In the next article, we’ll look at an interesting React hook called useMemo
, which allows us to optimize our components’ speed.