Why I Stopped Using useEffect (And You Should Too) π«βοΈ
Let me guess. Your React component looks like this:
useEffect(() => {
fetchData().then(setData);
}, []);
It works. But in 2025, itβs a code smell.
With React 19 and the rise of React Compiler & RSC, blindly using useEffect is making your app slower, buggier, and harder to maintain. Hereβs what to do instead.
The 3 Silent Killers of useEffect β οΈ
- Race Conditions β Component unmounts? Old data wins.
- Waterfall Requests β Fetch β wait β fetch again.
- Double Rendering β StrictMode mounts twice = double API calls.
The Fix: React 19's use Hook + Suspense
Instead of useEffect, do this:
import { use } from 'react';
function UserProfile({ userPromise }) {
const user = use(userPromise);
return <div>{user.name}</div>;
}
β
No useEffect
β
No loading boilerplate
β
Built-in cancellation
Real-World Before/After π₯
β Old way (useEffect + useState)
const [data, setData] = useState(null);
useEffect(() => {
let ignore = false;
fetch('/api')
.then(res => res.json())
.then(json => !ignore && setData(json));
return () => ignore = true;
}, []);
β
New way (React 19)
import { use } from 'react';
function Dashboard() {
const data = use(fetchData()); // just works
return <Chart data={data} />;
}
43% less code. Zero race conditions.
But Wait β When Should You Keep useEffect? π€
Only for synchronizing with non-React worlds:
- Third-party widgets (maps, video players)
- Manual DOM measurements
- Global event listeners
For data fetching, derived state, or user interactions β avoid it.
Your Turn π
Do you still use useEffect for API calls? Have you tried use or TanStack Query?
Drop a comment with your worst race-condition horror story β best one gets a shoutout in my next post!
*Liked this? β₯οΈ Follow me for more React 19 deep dives. *
Top comments (0)