In React, useEffect is a powerful tool. It lets your component “talk” to things outside of React — like setting up a timer, syncing data with a server, or working with the browser directly (e.g. changing the page title). This is useful when you're working with external systems.
But here’s the thing: many people use useEffect even when they don’t need to.
Using unnecessary useEffect can:
- Make your code harder to read
- Introduce bugs
- Make your app slower
Let’s understand when you don’t need an useEffect, and what you should do instead.
🚫 Don’t Use Effect to Transform Data
Suppose you’re combining first and last names into a full name. You might think of using an Effect to do this:
import { useState, useEffect } from 'react';
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
// ❌ Unnecessary useEffect
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
}
This looks okay, but it’s overkill. You’re using an Effect to calculate something that React can do naturally during rendering.
Here’s a better way:
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
// ✅ No Effect needed
const fullName = firstName + ' ' + lastName;
}
It’s simpler, faster, and easier to understand. React will automatically re-render the component when firstName or lastName change, and fullName will be updated.
🚫 Don’t Use Effects to Handle User Events
You also don’t need an Effect to update the state after a button click or input change.
Here’s a common mistake:
function Counter() {
const [count, setCount] = useState(0);
const [double, setDouble] = useState(0);
// ❌ Don't use Effect for derived state
useEffect(() => {
setDouble(count * 2);
}, [count]);
return (
<>
<button onClick={() => setCount(count + 1)}>Increment</button>
<p>Double: {double}</p>
</>
);
}
Instead, calculate double directly:
function Counter() {
const [count, setCount] = useState(0);
// ✅ No Effect needed
const double = count * 2;
return (
<>
<button onClick={() => setCount(count + 1)}>Increment</button>
<p>Double: {double}</p>
</>
);
}
You only need to store the state that changes independently. If you can compute a value from the existing state, just compute it.
✅ When Do You Need an Effect?
You need an Effect when you’re dealing with something outside React. Here are some examples:
✅ Fetching Data from an API
useEffect(() => {
fetch('/api/user')
.then(res => res.json())
.then(data => setUser(data));
}, []);
You’re fetching data from a server — that’s an external system.
✅ Subscribing to an Event
useEffect(() => {
function handleResize() {
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
You’re interacting with the browser (outside React), so useEffect is necessary.
✅ Setting a Timer
useEffect(() => {
const id = setInterval(() => {
console.log('Tick');
}, 1000);
return () => clearInterval(id); // Cleanup
}, []);
Again, this involves something external (the browser timer), so you need an Effect.
🎯 Summary
Before using useEffect, ask yourself:
🔹 Am I syncing with something outside React?
🔹 Or can I just calculate this during render?
Use the state only for data that can’t be calculated. Avoid redundant state and unnecessary Effects. It makes your React code cleaner, faster, and easier to debug.
🔁 Quick Reference
Do You Need useEffect?
- Combining two pieces of state. ❌ No
- Updating derived values. ❌ No
- Responding to user clicks. ❌ No
- Fetching data from the API. ✅ Yes
- Setting timers or intervals. ✅ Yes
- Subscribing to external events. ✅ Yes
Let React do the heavy lifting for you — only use Effects when truly needed!
Thank you for reading! Feel free to connect with me on LinkedIn or GitHub.
Top comments (0)