[React.js] - Part 11. React Hooks - useEffect Hook

Ace Lennox
The useEffect
Hook is a powerful tool in React, allowing developers to handle side effects within functional components. Side effects include tasks like fetching data, updating the DOM directly, or managing timers. This guide will help you understand how to use useEffect
effectively, with examples that are clear and practical.
What is useEffect
?
The useEffect
Hook enables you to perform tasks outside of React's rendering cycle. This is essential for managing operations that interact with the outside world, such as API requests or browser-based side effects.
How useEffect
Works
The useEffect
Hook takes two arguments:
A function where the effect logic is defined.
An optional dependency array that specifies when the effect should run.
useEffect(() => {
// Effect logic here
}, [dependencies]);
If you omit the dependency array, the effect will run on every render.
Side Effects in Action: Examples
Example 1: Displaying a Message After Loading
Let’s create an example where a message appears 2 seconds after the component renders:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
function WelcomeMessage() {
const [message, setMessage] = useState("");
useEffect(() => {
const timer = setTimeout(() => {
setMessage("Welcome to our website!");
}, 2000);
// Cleanup to avoid memory leaks
return () => clearTimeout(timer);
}, []); // Runs only once after the initial render
return <h1>{message}</h1>;
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<WelcomeMessage />);
Here, setTimeout
is used to simulate a delay, and the cleanup function ensures that the timer is cleared when the component unmounts.
Example 2: Fetching Data from an API
Imagine fetching user data from an API and displaying it on the screen:
function UserData() {
const [user, setUser] = useState(null);
useEffect(() => {
async function fetchUser() {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
const data = await response.json();
setUser(data);
}
fetchUser();
}, []); // Runs once after the initial render
if (!user) return <p>Loading...</p>;
return (
<div>
<h1>{user.name}</h1>
<p>Email: {user.email}</p>
</div>
);
}
The empty dependency array ensures the API call runs only once, after the component is first rendered.
Example 3: Updating a Title Based on State
Let’s update the document’s title whenever the number of clicks changes:
function ClickTracker() {
const [clicks, setClicks] = useState(0);
useEffect(() => {
document.title = `You clicked ${clicks} times`;
}, [clicks]); // Runs whenever 'clicks' changes
return (
<div>
<button onClick={() => setClicks((prev) => prev + 1)}>Click Me</button>
</div>
);
}
The dependency array [clicks]
ensures the effect runs only when the clicks
state changes.
Cleanup in useEffect
Some effects, like timers, event listeners, or subscriptions, require cleanup to prevent memory leaks.
Example 4: Event Listener Cleanup
Here’s an example of setting up and cleaning up an event listener:
function WindowSize() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", handleResize);
// Cleanup the event listener
return () => window.removeEventListener("resize", handleResize);
}, []); // Runs only on mount and unmount
return <h1>Window width: {width}px</h1>;
}
Best Practices for useEffect
Specify Dependencies Clearly: Always include all state and props the effect depends on.
Use Cleanup Functions: Clean up side effects like timers or listeners to avoid memory leaks.
Avoid Unnecessary Effects: Keep logic inside
useEffect
strictly for side effects. Calculations or transformations can often be handled directly in the render.Optimize Dependency Arrays: Include only the necessary dependencies to prevent redundant executions.
Summary
The useEffect
Hook is an indispensable part of React development. It allows you to manage side effects effectively, making your components dynamic and interactive. Whether you're fetching data, managing events, or updating the DOM, useEffect
gives you the tools to do it cleanly and efficiently.
Experiment with these examples to see how useEffect
can bring your React applications to life!
Source Code
The complete source code for this part is available on GitHub