Stop using useEffect for API calls in Reactjs !! Here's the pattern I see in almost every codebase: // ❌ "Fetching on mount" — the way everyone does it useEffect(() => { fetchUser(userId).then(data => setUser(data)); }, [userId]); Looks fine, right? Here's what nobody tells you: → This runs AFTER render (so your UI flashes) → There's a race condition if userId changes fast → No cleanup = memory leak on unmount → React 18 runs it TWICE in dev mode — and most people don't know why The correct version: useEffect(() => { let cancelled = false; fetchUser(userId).then(data => { if (!cancelled) setUser(data); }); return () => { cancelled = true; }; // cleanup }, [userId]); But honestly? The React team is moving away from useEffect for data fetching entirely. The real answer is: → React Query / TanStack Query → SWR → Next.js server components (no useEffect needed AT ALL) useEffect was never meant to be a data fetching tool. It was designed for syncing React with outside systems — DOM APIs, WebSockets, third-party libraries. We misread the docs. We built habits. And now millions of React apps have race conditions baked in. The myth: "useEffect is how you fetch data in React" The truth: useEffect is an escape hatch, not a pattern. For more insightful content checkout below: 🟦 𝑳𝒊𝒏𝒌𝒆𝒅𝑰𝒏 - https://lnkd.in/dwi3tV83 ⬛ 𝑮𝒊𝒕𝑯𝒖𝒃 - https://lnkd.in/dkW958Tj 🟥 𝒀𝒐𝒖𝑻𝒖𝒃𝒆 - https://lnkd.in/dDig2j75 or Priya Frontend Vlogz 🔷 𝐓𝐰𝐢𝐭𝐭𝐞𝐫 - https://lnkd.in/dyfEuJNt #frontend #javascript #react #reactjs #html #css #typescript #es6 #interviewquestions #interview #interviewpreparation
Learned new thing 👍👍👍
Because the cancelled is not a ref, it will be redeclared and set to false again (strict mode, effects run twice). So unless you use a ref guard, this won't achieve your goal.
One other solution would be to use abortController, with that we can abort the network request itself on race condition so our state won't receive duplicate setState call at all.
Good points. But I’d frame it slightly differently: useEffect isn’t wrong for data fetching — it’s just low-level and easy to misuse. Libraries like React Query or SWR solve caching, deduping, retries and race conditions out of the box, which is why most teams prefer them now.