useQuery or useMutation?
What's the best way to handle side effects with React Query when making API calls in a chat application?
I'm building a chat app where each API response needs to update a conversation array in state. Currently using
useQuery
with side effects in the queryFn
, but I know this isn't ideal. Here's my current code:
Is useMutation
a better choice here? Or should I handle state updates in a separate useEffect
?6 Replies
Personally, I'd do
useQuery
to fetch conversation history, and then useMutation
to post new question. Within the mutation, you are free to invalidate or even override the data cached by useQuery
(I'd override the cache if you don't want to pull all the data from conversation history too often).
But it kinda depends on where the conversation messages are stored.useQuery
for GET
requests
useMutation
from actions like: POST
PUT
DELETE
Even if they’re stored in local storage it doesn’t matter to React Query, it just needs an async function to track.
I would do that too, useQuery to get the messages and every time I send a new message that’ll be a useMutation “mutate” fn and I’ll override the messages on onMutate to incluye my message before you I get a response back from the server, then onSuccess trigger an invalidation in to make the query trigger again.
I believe there’s a way you can make the useQuery only take the last 2 messages that will be the one you sent (and optimistically showed on the UI via onMutation) and the one from the server. Maybe infinite query not sure, but might work
That way you don’t pull the whole conversation over and over again, just the last 2 that are needed
Even if they’re stored in local storage it doesn’t matter to React Query, it just needs an async function to track.True, although in such case I'd consider skipping
useQuery
entirely as there is not much benefits from using it (maybe apart from code consistency with other data sources which is actually a good reason). With indexeddb its true that you get data asynchronously, but it's such unnoticeable delay, there is pretty much no need for caching, invalidation, keys etc, so simple custom hook would be enough.Oh my bad, I didn’t mean it as an actual solution for local storage, I was just trying to say that as long as you pass an async function to React Query it doesn’t care what it is
We are not storing conversation history as of now, so its just one-way traffic right now.
We are kind of using
POST
for everything; not optimal ik but that's what the backend guys have done. So, the above rule might not work in this case.