Hooks are new features incorporated into React 16.8. and the newer versions. They basically help you use React features without writing a class.
In this guide, we are going to cover why this hook exists and how to use it in React.
If you started your React journey before version 16.8, then you have to unlearn lifecycle methods and instead think in effects.
The useEffect hook lets us express different kinds of side effects after a component renders. In case you are wondering what side effects are, relax, you will understand in a second.
Side effects are unpredictable actions performed with the "outside world." Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. Regardless of knowing what this term means, you have most likely used it.
There are two common kinds of side effects in React components: those that don’t require cleanup, and those that do.
Side Effects Without Cleanup
Network requests, manual DOM mutations, and logging are common examples of effects that don’t require a cleanup. We can run them and immediately forget about them.
Side Effect With Cleanup
Some effects require cleanup to reduce memory leaks.
Timeouts, subscriptions, event listeners, and other effects that are no longer needed should be disposed.
This is done by including a return function at the end of the useEffect Hook.
useEffect is a tool that lets us interact with the external world but does not affect the rendering or performance of the component that it's in. React enables multiple useEffect instances inside a React functional component. The code can be broken down into multiple Hooks containing logically related code in a single function.
By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates.
It is a combination of componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods in class-based components.
Why useEffect is defined inside a component?
“useEffect” function is defined inside the component so that the variables and the functions defined inside the components can be accessed directly. If you are familiar with closures in JavaScript, you will probably be having an "aha!" moment now. And if you don't, it is not a problem.
Closures are functions that are nested in other functions and simply allows variables outside of the scope of a function to be accessed. It takes advantage of the concept of Closure to provide access to the local functions and variables defined inside a function.
How to use the useEffect hook
- We import useEffect from "react"
- We call it above the returned JSX in our component
- We pass it two arguments: a function and an array
import { useState, useEffect } from "react";
function Counter() {
const [count, setCount] = useState(0);
const [calculation, setCalculation] = useState(0);
useEffect(() => {
setCalculation(() => count * 2);
console.log(calculation);
}, [count]); // <- add the count variable here
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
<p>Calculation: {calculation}</p>
</>
);
}
The function passed to useEffect is a callback function which will be called after the component DOM renders. The side Effects are performed inside this function.
The second argument is an array, called the dependencies array. This array includes all of the values the side effect relies on. What this array will do is it will check and see if a value has changed between renders. If so, it will execute our use effect function again. We can optionally pass dependencies to useEffect in this array.
1. No dependency passed:
useEffect(() => {
//Runs on every render
});
2. An empty array:
useEffect(() => {
//Runs only on the first render
}, []);
3. State values passed into array:
useEffect(() => {
//Runs on the first render
//And any time any dependency value changes
}, [state]);
Summary
useEffect is a tool that lets us interact with the external world but does not affect the rendering or performance of the component that it's in.
By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed, and call it later after performing the DOM updates.
It is a combination of componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods in class-based components.
We pass two arguments: a function and an array into a useEffect hook.
Top comments (11)
It's an easy way of explaining and understanding how
useEffect
works. But I agree. Maybe it would be better to create an example using something like window dimensions which from my point of view requires theuseEffect
hook. Needed for adding and removing the event listener.useWindowDimensions custom hook
From React docs
The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect.
Please have a look over the updated documentation:
Thank you!
For those just getting started with useEffect, I highly suggest using something that provides intellisense about the hook's dependency array.
It's straightforward once you're used to the concept, but in the beginning, it will save you lots of headaches.
Thanks for the explanation. But I still struggling to understand this concept. Can you explain it with a more practical app or example. Please share if you have any YT link etc.
I think this Youtube video by WebDevSimplified will help you get a clearer picture.
youtu.be/0ZJgIjIuY7U
Nice article, I like it :D
I'm glad you found it useful.
I've recently written a post about useEffect, specifically about the dependency array. Because I tend to forget how to use it right. You find it here if you like: chrisko.io/posts/useEffect-hook-de...
It was an amazing read..
Thanks for your addition. This isn't a sophisticated example,it was just to help beginners up and running.