From Confusion to Clarity: Understanding useEffect in React
I have been using React for the past six months, but one concept always confused me — useEffect
. No matter how many times I encountered it, I struggled to understand when and how to use it properly. However, this week, I decided to focus entirely on useEffect
and finally cleared all my doubts. In this article, I will share everything I’ve learned to help others who might be facing the same confusion.
What is useEffect
?
useEffect
is a built-in React Hook 🪝 that allows you to handle side effects in functional components. Side effects include
- when component re-renders
- when component mounts
- The State of a value change
Fetching data
Updating the DOM
Setting up subscriptions
or Working with timers-intervals
things that go beyond rendering UI elements. Before React Hooks, side effects were handled using lifecycle methods in class components like componentDidMount
, componentDidUpdate
, and componentWillUnmount
. However, useEffect
simplifies this process for functional components.
For more info about Side effects visit https://refine.dev/blog/useeffect-cleanup/#what-are-side-effects
UseEffect using Patterns:
useEffect(() => {}) - Runs every re-renders
useEffect(() => {},[]) - Runs only on mounts
useEffect(() => {}, [dep]) - Runs on mount + when value changes
- UseEffect without Dependency Array
import { useEffect, useState } from "react"
export const CounterFunc = () => {
const [count,setCount] = useState(0)
return (
<>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
</div>
</>
)
}
What we done here that we create basic CounterFunction and use add default css class to parent div for more interactive look.
useEffect( () => {
document.title = `Count is ${count}`
console.log("UseEffect renders")
})
2. UseEffect with Empty Dependency Array
Let use same code above and explore what empty array do to our current logic.
useEffect( () => {
document.title = `Count is ${count}`
console.log("UseEffect renders")
},[])
// Adding Console.log for more understanding
3. UseEffect with Dependency Array
Let’s add more code to understand dependency array.
const [colour,setcolour] = useState("green")
function handlecolor(){
return setcolour(c => c === "green" ? "red" : "green")
}
<button onClick={handlecolor}>
Change Colour
</button>
<p style={{color: colour}}>Colour: {colour}</p>
Here is full code
import { useEffect, useState } from "react"
import '../../App.css'
const CounterFunc= () => {
const [count,setCount] = useState(0)
const [colour,setcolour] = useState("green")
useEffect( () => {
document.title = `Count is ${count} ${colour}`
console.log(`UseEffect renders ${colour} `)
})
function handlecolor(){
return setcolour(c => c === "green" ? "red" : "green")
}
return (
<>
<div className="card">
<p style={{color: colour}}>Colour: {colour}</p>
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<button onClick={handlecolor}>
Change Colour
</button>
</div>
</>
)
}
export default CounterFunc;
Let’s see What we have done yet.
Perfect ! Working as expected, As we go with wihout dep array it triggers useEffect on every Re-render.
useEffect( () => {
document.title = `Count is ${count} ${colour}`
console.log(`UseEffect renders ${colour} `)
},[count])
What if we add both color and count state to dependency array.
I think Now You Understand UseEffect better. So we need to keep moving 🚲.
Real-World Example:
- Setting Width and Height of Screen
import React , {useState,useEffect} from 'react'
const Listnersideeffects = () => {
const [width,setwidth] = useState(window.innerWidth)
const [height,setheight] = useState(window.innerHeight)
const handleresize = () => {
setwidth(window.innerWidth)
setheight(window.innerHeight)
}
window.addEventListener("resize", handleresize)
console.log("Event listner added")
return (
<>
<p>Window width: {width}</p>
<p>Window Height: {height}</p>
</>
)
}
export default Listnersideeffects
What if we use that logic in useEffect ?
useEffect(() => {
window.addEventListener("resize", handleresize)
console.log("Event listner added")
},[])
Boom 🎆
Cleanup Logic — Return Function in UseEffect
useEffect
cleanup is a function in the useEffect
Hook that saves applications from unwanted behaviors by cleaning up effects.
return(() => {
window.removeEventListener("resize",handleresize)
console.log("Event listner Removed")
})
When to use UseEffect ?
- Data Fetching
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos')
.then(res => res.json())
.then(data => setData(data));
}, []);
- DOM Manipulations
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
- Event listeners
useEffect(() => {
window.addEventListener("keydown", handleUserKeyPress);
}, [handleUserKeyPress]);;
That’s it from my side. Here is some references and useful assest:
- Bro Code UseEffect: https://shorturl.at/qdumr
- https://refine.dev/blog/useeffect-cleanup/
Happy Learning 😃