React’s useEffect
hook is a cornerstone of functional component development, enabling developers to handle side effects like data fetching, DOM manipulation, and subscriptions. While incredibly powerful, useEffect
is often misunderstood, leading to performance bottlenecks and tricky bugs. This article’ll uncover the best practices for using useEffect
, common pitfalls to avoid, and how modern JavaScript can make your React code even more efficient.
It’s crucial also to stay updated on the core JavaScript language that underpins React. My eBook, "JavaScript: From ES2015 to ES2023", is an excellent resource to deepen your knowledge of modern JavaScript features that are essential for React development.
Let’s get started!
What is useEffect
?
useEffect
is a hook that lets you perform side effects in function components. It’s React’s replacement for lifecycle methods like componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Syntax Overview:
useEffect(() => {
// Effect logic
return () => {
// Cleanup logic (optional)
};
}, [dependencies]);
Best Practices for useEffect
1. Use the Dependency Array Correctly
The dependency array ensures that your effect only runs when specific values change. Always include all variables used inside the effect. Missing dependencies can lead to bugs or stale data.
Example:
useEffect(() => {
console.log(`Current count is: ${count}`);
}, [count]); // Runs only when `count` changes
Pro Tip: Use a linting tool like eslint-plugin-react-hooks
to catch missing dependencies.
2. Separate Concerns with Multiple Effects
Each useEffect
should handle a single concern. Combining multiple responsibilities in one effect makes your code harder to debug and maintain.
Example:
useEffect(() => {
console.log("Component mounted");
}, []);
useEffect(() => {
document.title = `New count: ${count}`;
}, [count]);
3. Always Clean Up Side Effects
To avoid memory leaks, clean up side effects like subscriptions or timers when the component unmounts or the effect re-runs.
Example:
useEffect(() => {
const timer = setInterval(() => {
console.log("Timer running");
}, 1000);
return () => clearInterval(timer); // Cleanup
}, []);
4. Avoid Overusing useEffect
Not all logic belongs in useEffect
. For example, you don’t need useEffect
for derived state or simple computations.
Bad Example:
useEffect(() => {
setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);
Good Example:
const fullName = `${firstName} ${lastName}`;
5. Use Custom Hooks for Reusable Effects
Extract repeated useEffect
logic into custom hooks to simplify your components and promote code reuse.
Example:
const useFetchData = (url) => {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const response = await fetch(url);
const result = await response.json();
setData(result);
};
fetchData();
}, [url]);
return data;
};
Usage:
const data = useFetchData("/api/data");
Common Pitfalls of useEffect
1. Forgetting Dependencies
Missing dependencies can cause your effect to use outdated values or skip necessary updates. Always list every variable used in the effect.
2. Creating Infinite Loops
Updating state inside an effect without proper conditions can create infinite render loops.
Bad Example:
useEffect(() => {
setCount(count + 1); // Triggers re-render, causing an infinite loop
}, [count]);
Fix:
useEffect(() => {
if (count < 10) {
setCount(count + 1);
}
}, [count]);
3. Memory Leaks
Forgetting to clean up effects like event listeners or timers can lead to memory leaks, especially in larger applications.
Bad Example:
useEffect(() => {
window.addEventListener("resize", handleResize);
}, []); // Cleanup missing
Fix:
useEffect(() => {
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
4. Overcomplicating Effects
Don’t overuse useEffect
for tasks that can be handled directly in render or with derived state.
How Modern JavaScript Helps in useEffect
React and modern JavaScript go hand-in-hand. Features like async/await
, destructuring, and optional chaining can make your useEffect
logic cleaner and more efficient.
Example: Using async/await
in Effects
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("/api/data");
const result = await response.json();
setData(result);
} catch (error) {
console.error("Error fetching data:", error);
}
};
fetchData();
}, []);
Conclusion
Mastering useEffect is essential for building robust React applications. By following best practices, avoiding common pitfalls, and leveraging modern JavaScript features, you can write clean, maintainable, and efficient code.
Deepen Your Knowledge: Modern JavaScript is the backbone of React. My eBook, "JavaScript: From ES2015 to ES2023", is a complete guide to mastering essential ES features, from destructuring to the latest advancements in ES2023. This knowledge is key to writing efficient, maintainable React code.
Top comments (20)
Isn't it better to use a library like tanstack/react-query rather than plain useEffect to make developer's life easier?
More dependence, yay JavaScript.
Tell me more about this react-query
interesting, have you tried using Remix.js, will reduce client code by 70%
Pro-Tip: Use literally anything other than React and you won't need to spend half your time learning workarounds to get the thing to work without blowing up.
#JustTryVue
#IMeanWillYouAtLeastTryIt
#ItsSixTimesFaster
#AndFree
#HaveYouSeenTheVueDevTools
#OMGPiniaAloneIsWorthIt
#PleaseStopHittingYourself
I am sorry but this is literally one the worst advices i have ever seen.
Every tool has pros and cons of its own and having cons doesnt mean it sucks.
I am a 5+ years a React user, sure there were times of confusion and frustration when i first started learning it but it was all worth it.
React will definitely make you a better js developer, it may seem like taking the hard route but it pays off in the end.
You will get to know more about the advanced concepts and topics of js through react since it relies heavily on those concepts.
React will also expose you to different ways of architecting your app since react doesnt have an explicit or opinionated way of structuring your code it gives you the complete freedom to choose your own architecture based on your needs, how large or small your app is.
I'm sorry friend, but literally every "pro" you mentioned here is true of all other JS Frameworks in 2025, and actually far more so in most cases. The problems with React are numerous and exclusive to it. You need to switch to ANYTHING else and then you will understand why React gets made fun of so much. The most impressive thing about React is, over the years, despite the landscape for JS frameworks changing so much, and React itself changing so much, it has somehow consistently been the worst option at all times. For different reasons, at different moments in time, but always, from a technical perspective, the worst choice. Are you afraid of trying something new? Then go with Solid.js, it's basically "React but it doesn't suck as much". Are you wanting some street cred? Go with Svelte. Do you want the objectively best option, because it stole all the best ideas from everyone else and did them better? Go with Vue. Do you want money? Even Angular is better than React, not by a lot, but it is. And those are just the big ones, there are so many more. Branch out, your future self will thank you. Don't be a React developer, don't even be a JavaScript developer, be a Software Developer.
You went for the assumption that i havent tried other tools which is weird.
Also saying i needed to branch out and be a software developer rather than being a react dev and blah blah .... just show you are full of yourself.
First of all I think you are missing the point here, i am not advicing or pushing anyone to swap tools like you strongly did , what i said is that naturally every thing in this world being a tech related or an objet has its goods and bads.
Giving a pro tip by saying to ppl to switch to some other tools is again and i am not gonna change my opinion is "horrendous advice".
I bet you know that reactjs can not be compared with vue and angular since its a library not a framework.
So the comparison thing you kept going about in your comment doesnt weigh to anything literally.
And if you dont know about this maybe you go read about reactjs and nextjs so next time you give a "PRO TIP" on a fair and objective basis rather than keep saying nonesense.
Preaching against reactjs is like saying those big companies like airbnb or booking dont understand business and that they should desperately hire you cause you and only will be able to put them on the right track :D
These anti-react devs are from the same womb as rust Devs.
There's a reason why we outsource so many React jobs overseas, but you never see Rust or Vue jobs get outsourced. It's because those are actual desirable jobs. No one wants to work with COBOL, FORTRAN, old PHP, or React.
People outsource so many React jobs overseas, because it is cheaper.
If Vue or Rust is as popular, it will be out sourced.
You all have been saying PHP is dead for like 15 years. Yet it still powers a huge chuck of the web.
Wanted to ask. Does Vue have something similar to react native for mobile and even desktop app development?
Yes, NativeScript-Vue is a common choice. Tauri is popular if you use Rust. There is also "Vue-Native" which is a Vue wrapper around React-Native, it's not commonly recommended unless there is a specific React-Native library your app can't function without, or you are transitioning away from React-Native. There is also Ionic/Capacitor, much simpler if performance isn't a major requirement. And then Quasar if you need more than just Mobile. And of course, there's always the option of using a PWA which is pretty underrated, as many of the most common "native" features people want are available via this API now.
Hard disagree. If React is too difficult for you it’s not because React is bad, your skill level likely isn’t where it needs to be. Level up.
"Hey, you shouldn't use that gun, it doesn't have a safety and it always points at your foot". "HA! If you can't move your foot fast enough not to shoot it, it sounds like you have skill issues. Level up bro! (proceeds to shoot self in foot, then puts gold medal around his own neck and smiles while bleedning out)"
VueJS is still second best option.
You mean popular, not best. Read this next sentance as many times as it takes for you to understand and internalize it.
There is no correlation between quality and popularity.
Nah, its popular because it's simply the best whether you agree or not
After React
Very useful tips! I've been struggling this hook in my projects, specially for fetching data or syncing with another component states. Thank you for sharing these tips 🙌
Some comments may only be visible to logged-in visitors. Sign in to view all comments.