React JS - useEffect


UseEffect
The useEffect
hook in React is a powerful tool for managing side effects in functional components. It allows you to run some code after rendering a component, and also to handle cleanup after the component is unmounted.
The basic syntax of useEffect
is as follows:
1 import { useEffect } from 'react';
2
3 function MyComponent() {
4 useEffect(() => {
5 // code to run after rendering
6 }, [dependencies]);
7 return <div>Hello World!</div>;
8}
In this example, the useEffect
hook takes two arguments:
A function to run after rendering (the "effect" function)
An array of dependencies (optional)
How it Works
Here's a step-by-step breakdown of how useEffect
works:
Rendering: The component is rendered, and the
useEffect
hook is called.Effect Function: The effect function is executed after the component has been rendered.
Dependencies: If the dependencies array is provided, React will check if any of the dependencies have changed since the last render. If they have, the effect function will be re-run.
Cleanup: If the component is unmounted, the effect function will be called with a
cleanup
function as an argument. This allows you to perform any necessary cleanup.
Example Use Cases
1. Fetching Data
1 import { useState, useEffect } from 'react';
2
3 function MyComponent() {
4 const [data, setData] = useState([]);
5 useEffect(() => {
6 fetch('https://jsonplaceholder.typicode.com/posts')
7 .then(response => response.json())
8 .then(data => setData(data));
9 }, []);
10 return <div>Data: {data}</div>;
11}
In this example, we use useEffect
to fetch data from an API after the component has been rendered.
2. Handling Events
1 import { useState, useEffect } from 'react';
2
3 function MyComponent() {
4 const [count, setCount] = useState(0);
5 useEffect(() => {
6 document.addEventListener('click', () => setCount(count + 1));
7 return () => document.removeEventListener('click', () =>
setCount(count + 1));
8 }, [count]);
9 return <div>Count: {count}</div>;
10}
In this example, we use useEffect
to handle a click event and update the component state.
3. Animations
1 import { useState, useEffect } from 'react';
2
3 function MyComponent() {
4 const [animate, setAnimate] = useState(false);
5 useEffect(() => {
6 const animation = setTimeout(() => setAnimate(true), 1000);
7 return () => clearTimeout(animation);
8 }, []);
9 return <div className={animate ? 'animate' : ''}>Hello World!</div>;
10 }
In this example, we use useEffect
to animate a component after a delay.
Best Practices
Always provide a dependencies array to ensure the effect function is re-run when necessary.
Use the
cleanup
function to perform any necessary cleanup when the component is unmounted.Avoid using
useEffect
for complex logic or computations. Instead, use a separate function or a library like Redux.
Fetching Data After the Component is Rendered
// Calling an API with useEffect using Promise
import { useEffect } from "react";
const url = "https://jsonplaceholder.typicode.com/posts";
export function FetchData() {
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => {
console.log(data);
});
}, []);
return <div></div>;
}
//calling an API with useEffect using async await
import { useEffect } from "react";
const url = "https://jsonplaceholder.typicode.com/posts";
export function FetchData() {
async function fetchedData() {
const response = await fetch(url)
const data = await response.json()
console.log(data);
}
useEffect(() => {
fetchedData();
},[]);
return <div></div>;
}
Show Data Using UseEffect
import { useEffect, useState } from "react";
import { User } from "./User";
const URL = "https://jsonplaceholder.typicode.com/users";
export function FetchData() {
const [users, setUsers] = useState([]);
//for loading Effect => Throttling
const[isLoading, setIsLoading] = useState(true);
//For error checking
const [error, setError] = useState(false)
async function fetchedData() {
const response = await fetch(URL);
if (response.status >=200 && response.status<=299) {
const data = await response.json();
setUsers(data);
}
else{
setError(true)
}
setIsLoading(false)
}
useEffect(() => {
fetchedData();
}, []);
if(isLoading){
return <h1>Loading ....</h1>
}
if (error) {
return <h1>Something went Wrong</h1>
}
return (
<div>
{users.map((user) => (
<User key={user.id} {...user}/>
))}
</div>
);
}
Cleanup for Fetching Data
//App.jsx
import { useState } from "react";
// import { CleanupFunctionDemo } from "./CleanupFunctionDemo";
// import { MouseMoveEvent } from "./MouseMoveEvent";
import {FetchData} from "./FetchData"
//Strict Mode -> for useEffect ->
//useEffect run
//cleanup function
//useEffect run again
function App() {
const [showComponent, setShowComponent] = useState(true);
return (
<>
{/* <ExampleUseEffect /> */}
{/* <FetchData/> */}
<label htmlFor="showComponent">show Component</label>
<input
type="checkbox"
name="showComponent"
id="showComponent"
checked={showComponent}
onChange={() => setShowComponent(!showComponent)}
/>
{showComponent && <FetchData />}
</>
);
}
export default App;
//fetchData.jsx
import { useEffect, useState } from "react";
import { User } from "./User";
const URL = "https://jsonplaceholder.typicode.com/users";
export function FetchData() {
const [users, setUsers] = useState([]);
//for loading Effect => Throttling
const[isLoading, setIsLoading] = useState(true);
//For error checking
const [error, setError] = useState(false)
useEffect(() =>{
//for Aborting on fetching the data
const controller = new AbortController();
const signal = controller.signal;
async function fetchedData() {
//we can pass signal onject
const response = await fetch(URL, { signal:signal });
if (response.status >=200 && response.status<=299) {
const data = await response.json();
setUsers(data);
}
else{
setError(true)
}
setIsLoading(false)
}
fetchedData();
//this return is for cleanup function for useEffect
return ()=>{
console.log('aborting request....');
controller.abort()
}
}, []);
if(isLoading){
return <h1>Loading ....</h1>
}
if (error) {
return <h1>Something went Wrong</h1>
}
return (
<div>
{users.map((user) => (
<User key={user.id} {...user}/>
))}
</div>
);
}
Cleanup Function Example
import { useEffect, useState } from "react";
//cleanup function
//1: before component unmount
//2: when there is some value in dependency array
//when value of counter changes
//component rendered
//cleanup function rendered
//useEffect rendered
export function CleanupFunctionDemo() {
console.log("component rendered");
const [counter, setcounter] = useState(0);
useEffect(() => {
console.log("useEffect rendered");
return function(){
console.log('cleanup function rendered');
}
}, [counter]);
return (
<>
<div>
<h3>Counter : {counter}</h3>
<br />
<button onClick={() => setcounter((prevCounter) => prevCounter + 1)}>
Increase
</button>
</div>
</>
);
}
Mouse Move Event
import React, { useEffect, useState } from "react";
export function MouseMoveEvent() {
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const handleMouseMove = (e) => {
console.log({ x: e.clientX, y: e.clientY });
setMousePosition({ x: e.clientX, y: e.clientY });
};
document.addEventListener("mousemove", handleMouseMove);
return () => {
console.log("cleanup function");
document.removeEventListener("mousemove", handleMouseMove);
};
}, []);
return (
<div>
<p>x: {mousePosition.x}</p>
<p>y: {mousePosition.y}</p>
</div>
);
}
GitHub Code : UseEffect
Subscribe to my newsletter
Read articles from Code Subtle directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Code Subtle
Code Subtle
At Code Subtle, we empower aspiring web developers through personalized mentorship and engaging learning resources. Our community bridges the gap between theory and practice, guiding students from basics to advanced concepts. We offer expert mentorship and write interactive, user-friendly articles on all aspects of web development. Join us to learn, grow, and build your future in tech!