AI Built with `useEffect` for Data Fetching (It Shouldn’t)
AI-generated React code often uses `useEffect` for data fetching — a pattern that causes race conditions, stale data, and duplicate network requests.
By Contributor · published 5/30/2026
`useEffect` is the right tool for synchronizing a component with an external system (timers, subscriptions, DOM APIs). It is the wrong tool for fetching server data.
The problems with `useEffect` data fetching are well-documented:
- No built-in caching — same data refetched on every mount
- No deduplication — multiple components trigger duplicate requests
- Race conditions — fast navigation can cause stale responses to overwrite fresh ones
- No automatic retry on failure
- No loading/error state management without manual boilerplate
AI tools generate `useEffect` fetch patterns because they match the training data — most pre-2023 React tutorials used this pattern. But the React community has broadly moved on.
As documented by React practitioners: “React in 2025 is about declarative data, not lifecycle effects.” ([DEV Community](https://dev.to/paulthedev/stop-using-useeffect-for-data-fetching-in-react-heres-a-better-way-2kkj))
The recommended replacement is [TanStack Query](https://rtcamp.com/handbook/react-best-practices/data-loading/), which provides out-of-the-box caching, deduplication, background refetching, retry logic, and abort signals:
```jsx
// Instead of useEffect + useState + fetch:
const { data, isLoading, error } = useQuery({
queryKey: ['users', userId],
queryFn: () => fetchUser(userId),
staleTime: 5 * 60 * 1000, // 5 minutes
});
```
## Why it matters
A dashboard with stale data is a trust problem. A race condition that occasionally shows the wrong user’s data is a security problem. Both are common `useEffect` failure modes that TanStack Query eliminates by design.
## Suggested next action
Search your codebase for `useEffect` calls that contain `fetch(` or `supabase.from(`. Evaluate whether TanStack Query would be a better fit for those data needs.