API Interaction Anti-Patterns
There are very few software patterns that are always an Anti-Pattern. Sometimes a pattern starts out ok, but leads to problems, or frustration (for us, or our users) over time.
Pessimistic API Interactions
The first anti-pattern is one I see quite often. You can make an argument that in certain situations, this is a reasonable approach, but often, I see entire applications built this way.
I think part of the problem is that when you, as a developer, are "locked in" and working on a feature, the delays and loading modals don't seem like much of a big deal. It is somewhat easier to implement a feature like this, and you've got code to ship!
However, an entire complex application that is littered with these creates a horrible experience for the users.
Optimistic API Interactions
The second anti-patterns shows up when we try to rectify the bad experience of the pessimistic API interactions pattern (above).
We decide to tell a little white lie. We change the state that our UI depends on in the optimistic hope that the server will eventually agree with our idea of what the state should be.
Optimism is a pretty good philosophy, in general, but can cause real problems when things don't go as you have planned.
This Pattern Is Enticing
I've used it. I've even taught it. Please avoid it. Even the pessimistic pattern is better in terms of reliability.
I Love TanStack Query, but it can't save you.
It doesn't help with this pattern. It is a pattern. It doesn't matter if you are caching the state in your own service, or hiding that by having TanStack Query hold it for you. You have to invalidate it (and reload) if you are mutating. And reloading your data after each mutation can cause modal blocks, but also I've had issues where the developer of the API doesn't implement caching properly and doesn't use techniques (like conditional GET requests) to invalidate the cache. So, you make a change, then reload, expecting to see that change reflected in the response, but it was (transparently) served from a cache (your browser, or an intermediary). Right now, the upcoming pattern (Outbox) is the best take for this kind of thing, IMO.