Day 4: Side Effects & Lifecycle
Day 4: Side Effects & Lifecycle
We know how to render UI (return JSX) and handle user interaction (useState). But what about things that happen outside the render flow? Like fetching data from an API, setting up a timer, or manually changing the document title?
These are called Side Effects, and we handle them with the useEffect hook.
The useEffect Hook
useEffect lets you perform side effects in functional components. It runs after the render.
import { useState, useEffect } from 'react';
function Timer() {
const [count, setCount] = useState(0);
// This runs after EVERY render
useEffect(() => {
document.title = `Count: ${count}`;
});
return <button onClick={() => setCount(count + 1)}>Click me</button>;
}
The Dependency Array
You rarely want an effect to run after every single render. We can control when it runs using the Dependency Array (the second argument).
1. Run Once (On Mount)
Passing an empty array [] tells React: âThis effect doesnât depend on any props or state, so run it ONLY once when the component first appears.â
useEffect(() => {
console.log('Component Mounted!');
}, []); // Empty array
This is perfect for API calls.
2. Run When Specific Data Changes
Pass variables into the array. The effect runs only when those variables change.
useEffect(() => {
console.log('Count changed to:', count);
}, [count]); // Runs only when 'count' changes
Data Fetching Example
Letâs fetch some users from a fake API.
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
// Define async function inside or use .then syntax
async function fetchUsers() {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await response.json();
setUsers(data);
}
fetchUsers();
}, []); // Run once on mount
return (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
}
Cleanup Function
Sometimes an effect needs to clean up after itselfâlike clearing a timer or removing an event listener. You do this by returning a function from useEffect.
useEffect(() => {
const interval = setInterval(() => {
console.log('Tick');
}, 1000);
// Cleanup function runs when component unmounts
return () => clearInterval(interval);
}, []);
If you donât clean up, you might get memory leaks or weird bugs when the component disappears.
Homework for Day 4:
- Create a component that fetches a random joke from
https://api.chucknorris.io/jokes/random. - Display the joke.
- Add a âGet New Jokeâ button that re-fetches data (hint: you might donât even need
useEffectfor the button click, but try triggering the effect by changing a state variable!).
Tomorrow, we organize our data with Lists & Keys!