Disclaimer:
- I used this blog to see my understanding of useEffect that i learned from other blogs as well as videos, if someone else is reading this, to test your knowledge you can learn about cleanup function in useEffect and write your own blog :).
- If you find any mistakes or has any question related to this, please comment.
- Have a good day everyone :D
What is useEffect?
According to React's official website. useEffect
is the hook we use to perform side effects(react just says the same thing but in a fancy way) .
So, what are side effects?
React’s main job is to render and re-render the UI based on changes, but that’s solely what it does. What if we want to send an HTTP request, change a global variable, or do something else after rendering that doesn’t include updating the UI? That’s what a side effect is.
In simpler words: The things we want our component to do beyond just rendering the UI are side effects. To achieve these side effects, we use the useEffect
hook.
But can we do it without useEffect
?
Consider this code:
import { useState } from "react";
export function Mango() {
const [bool, setBool] = useState(false);
const [name, setName] = useState("Not John Doe");
setTimeout(() => {
console.log("useEffect is niceeeee :)");
}, 2000);
return (
<>
<h1>{bool ? "I eat mango" : "You eat mango"}</h1>
<h1>My name is {name}</h1>
<button onClick={() => setBool(!bool)}> Who eats Mango? </button>
</>
);
}
Disclaimer: If running this code logs twice, that’s because Strict mode is enabled.
This console.log
statement above is a side effect too, right?
Does it do something other than rendering UI? Yes, it logs output to the console.
So Yes it is a side Effect! So, why do we need the useEffect
hook?
Well for now, in the above example console.log
will run after every re-render of component but what if we need the effect to happen only at the start, or only when a certain part of the component changes? That’s when useEffect
comes in handy—it enhances your component that way.
How does useEffect
work?
The syntax for useEffect
is:
useEffect(() => {}, [dependencies]);
useEffect
only runs after the render/re-render of the component.
useEffect
takes two parameters:
- First parameter: Setup Function
This is a function that you want to run whenever useEffect
is triggered (i.e., in our case, console.log()
like above). Here’s an example:
import { useState, useEffect } from "react";
export function Mango() {
const [bool, setBool] = useState(false);
const [name, setName] = useState("Not John Doe");
useEffect(() => {
console.log("useEffect is nicccceee :)");
}, []);
return (
<>
<h1>{bool ? "I eat mango" : "You eat mango"}</h1>
<h1>My name is {name}</h1>
<button onClick={() => setBool(!bool)}> Who eats Mango? </button>
</>
);
}
- Second Parameter: Dependency Array
Dependencies determine if useEffect
needs to run or not. It will only run if a dependency (or dependencies) placed in the second parameter (a.k.a., the dependency array) changes in the component.
import { useState, useEffect } from "react";
export function Mango() {
const [bool, setBool] = useState(false);
const [name, setName] = useState("Not John Doe");
useEffect(() => {
console.log("useEffect is nicccceee :)");
}, [bool]);
return (
<>
<h1>{bool ? "I eat mango" : "You eat mango"}</h1>
<h1>My name is {name}</h1>
<button onClick={() => setBool(!bool)}> Who eats Mango? </button>
</>
);
}
In this example, the dependency array has the bool
variable as a dependency. This means the setup function will only run on re-render if the bool
state variable changes.
Different Cases for Dependency Arrays
Case I - Array with Some Dependencies
import { useState, useEffect } from "react";
export function Mango() {
const [bool, setBool] = useState(false);
const [name, setName] = useState("Not John Doe");
const [value, setValue] = useState("Life");
useEffect(() => {
console.log("useEffect is nicccceee :)");
}, [bool, value]);
return (
<>
<h1>{bool ? "I eat mango" : "You eat mango"}</h1>
<h1>My name is {name}</h1>
<button onClick={() => setBool(!bool)}> Who eats Mango? </button>
</>
);
}
The useEffect
will run:
- For the very first time the component renders
- Every time there is a change in the state of
bool
orvalue
, but not if there’s a change in the state ofname
.
Case II - Empty Array (No Dependencies Listed)
import { useState, useEffect } from "react";
export function Mango() {
const [bool, setBool] = useState(false);
const [name, setName] = useState("Not John Doe");
const [value, setValue] = useState("Life");
useEffect(() => {
console.log("useEffect is nicccceee :)");
}, []);
return (
<>
<h1>{bool ? "I eat mango" : "You eat mango"}</h1>
<h1>My name is {name}</h1>
<button onClick={() => setBool(!bool)}> Who eats Mango? </button>
</>
);
}
useEffect
will run only the very first time the component renders.
But why only the first time?
For the first render, React detects the empty dependency array. It runs useEffect
, but when a re-render happens, it sees no change in values in the dependency array (because it’s empty), so it doesn’t re-run useEffect
.
Case III - Without the Second Argument
This last case is a bit different, though you may not use it as often.
import { useState, useEffect } from "react";
export function Mango() {
const [bool, setBool] = useState(false);
const [name, setName] = useState("Not John Doe");
const [value, setValue] = useState("Life");
useEffect(() => {
console.log("useEffect is nicccceee :)");
});
return (
<>
<h1>{bool ? "I eat mango" : "You eat mango"}</h1>
<h1>My name is {name}</h1>
<button onClick={() => setBool(!bool)}> Who eats Mango? </button>
</>
);
}
In this case, useEffect
will run after every re-render.
What’s the difference between this:
useEffect(() => {
console.log("useEffect is nicccceee :)");
});
and this:
console.log("useEffect is nicccceee :)");
The difference is that console.log()
runs during the evaluation/rendering of the component, but useEffect
runs after the component has evaluated/rendered.
Fun Fact: useEffect
Returns undefined
That's it for this blog, thanks for reading :)
Top comments (0)