DEV Community

Cover image for Stop Using useEffect for Data Fetching

Stop Using useEffect for Data Fetching

Devesh Sangwan on October 04, 2025

A few weeks ago, the React community was buzzing after the useEffect debacle at Cloudflare. If you’re not aware of what happened, don’t worry — I’l...
Collapse
 
antouni profile image
Antouni

Nice article. I liked it.

However, I have one big question, is it possible to combine redux with its asynchronous thunks (or another tool for centralization the data) and TanStack Query. And if possible, what is the best and elegant way?

Collapse
 
deveshsangwan profile image
Devesh Sangwan

Thanks! Glad you liked it 😊
Yes, you can use Redux and TanStack Query together since they serve different purposes.
Redux (or thunks) works best for client state such as UI elements, filters, and toggles.
TanStack Query is ideal for server state which comes from APIs and can change outside your app.

You can sync them by dispatching inside onSuccess, but it’s usually cleaner to let TanStack Query manage server data and keep Redux for UI logic.

Collapse
 
antouni profile image
Antouni

Fine! Thank you for explanation, it's very clear and i appreciate it. Waiting for your new articles ☺️.

Collapse
 
dominikdosoudil profile image
Dominik Dosoudil

onSuccess callback has been removed since doing exactly this was considered an anti-pattern. tkdodo.eu/blog/breaking-react-quer...

Stating that redux is for client state and TanStack Query is also clumsy. Not redux neither TanStack Query states that. Also TanStack Query is not only for syncing server data. It's a state management library that's convenient for any asynchronous data and actually making reactive state from them. Instead of fetch, it could be anything async. E.g. MediaDevices.getUserMedia which returns Promise.

Thread Thread
 
deveshsangwan profile image
Devesh Sangwan

You’re right that onSuccess, onError, and onSettled were removed from useQuery in v5 to discourage side effects during render. But are still available and recommended for useMutation, since mutations represent explicit user actions.
(Docs: tanstack.com/query/latest/docs/fra...)

I agree that TanStack Query can handle any async data, not just HTTP calls. But its core design and documentation describe it as an async state library optimized for server state, meaning data that can become stale, needs caching, or background refetching.
Redux or Zustand works better for client or UI state, such as filters, toggles, or input. TanStack Query is not intended to replace that kind of local state management.

So while it can be used for any promise-based data, the practical distinction still makes sense:

TanStack Query - Server or async state
Redux - Client or UI state

That’s also the pattern most teams follow.

Thread Thread
 
dominikdosoudil profile image
Dominik Dosoudil

useMutation is totally different story, the article isn't about it at all, it does not serve as wrapper around data synced into the client app. It rather helps monitor event based async requests.

The thing is that redux/zustand/... could also serve as storage for the promise based data however as lower level storage. TanStack Query brings another tools like caching or state tracking (isSuccess/isLoading/...) but with a tradeoff. There are use cases where TanStack Query does not fit and these situations need to be solved ad hoc however e.g. redux still can help holding the data.

Collapse
 
yehanny profile image
Yehanny Olivares

Great article, switching to TankStack Query, thanks!

Collapse
 
deveshsangwan profile image
Devesh Sangwan

Thanks! Glad you found it helpful.

Collapse
 
brense profile image
Rense Bakker

Tanstack query uses useEffect internally though...

Collapse
 
deveshsangwan profile image
Devesh Sangwan

True, it uses useEffect internally, but that’s the point.
It abstracts all the tricky parts like caching, retries, and race conditions so you don’t have to deal with them in every component.
The goal isn’t to avoid useEffect, but to use it in a safer, consistent way.

Collapse
 
brense profile image
Rense Bakker

That's a big assumption that tanstack query uses useEffect in a safe way 😛