Hey there, Fellow Coder! đ
Remember how we talked about State being the componentâs memory? Well, today weâre going to talk about its âsensesâ or âreactionsâ.
Weâre diving into useEffect.
A lot of people find this hook confusing. âWhen does it run?â, âWhy is it looping infinitely?!â, âWhat is this dependency array thing?â.
Relax. Grab your coffee. Weâre going to make this crystal clear. â
What is a âSide Effectâ?
Before we touch the code, letâs talk concept. In React, a componentâs main job is to render UI (show HTML).
But sometimes, your component needs to do things outside of just showing UI. things like:
- Fetching data from an API (getting data from the server).
- Setting a timer or interval.
- Changing the document title.
- Listening to window resize events.
These are called Side Effects. They are âside missionsâ that run alongside the main mission of rendering.
useEffect is the tool React gives us to handle these side missions.
1. The Basics: How to Use It
To use it, you import it just like useState.
import { useEffect, useState } from "react";
const Timer = () => {
const [count, setCount] = useState(0);
// This is the Effect
useEffect(() => {
console.log("Effect ran!");
document.title = `Count: ${count}`;
});
return <button onClick={() => setCount(count + 1)}>Click me: {count}</button>;
};
Wait, when does it run?
By default (like the code above), useEffect runs after every single render.
- Component appears (mount) -> Effect runs.
- You click button -> State changes -> Re-render -> Effect runs again.
This is often⊠too much. We usually donât want to fetch data every time a user clicks a button.
2. The Dependency Array []: controlling the Chaos
This is where the magic happens. The second argument of useEffect is an array []. This tells React:
âHey, only run this effect if THESE specific things change.â
Scenario A: The Empty Array []
useEffect(() => {
console.log("I only run ONCE when the component mounts.");
}, []); // <--- Empty array
This is perfect for things you only want to do once, like fetching data when the page loads. Itâs the modern replacement for componentDidMount.
Scenario B: Watching Specific Variables
useEffect(() => {
console.log("I run when 'count' changes!");
}, [count]); // <--- Watch 'count'
Now, the effect runs on mount, AND whenever count changes. If count stays the same, React skips the effect. Efficient! âĄ
3. The Cleanup Function: Donât Leave a Mess
Imagine you set up a party (an effect). When the party is over (component unmounts), you need to clean up the trash.
In code, this happens with things like Timers or Event Listeners. If you donât clean them up, they keep running in the background and eat up memory (memory leaks).
useEffect(() => {
const timer = setInterval(() => {
console.log("Tick Tock...");
}, 1000);
// This is the cleanup function
return () => {
clearInterval(timer); // Stop the timer!
console.log("Cleanup done!");
};
}, []);
React calls this cleanup function when:
- The component is removed from the screen (unmount).
- Before re-running the effect (if dependencies change).
Simple Analogy đ§
Think of useEffect like a Smart Sprinkler System for your garden (component).
- No Array: The sprinkler runs all the time, non-stop. (Bad idea, youâll flood the garden).
- Empty Array
[]: The sprinkler runs once when you first install it, then never again. - Array with
[sun]: The sprinkler runs only when the sun comes out. - Cleanup: Turning off the water so it doesnât leak when you move house.
Closing
Thatâs it!
useEffect is just a way to synchronize your component with the outside world.
- Default: Runs every render.
[]: Runs once on mount.[data]: Runs whendatachanges.- Return function: Cleans up the mess.
Master this, and youâve mastered 80% of modern React challenges. Next time, we might build something real with this.
Happy Coding! đ