Reputation: 3276
I'm working with react-query, using an infinite query, and I am having an issue. I am unable to get setQueryData
to refresh the cache and return a new first page. I have a hook that returns a method that adds the message to an InfiniteQuery cache.
I have found a workaround for this by simply invalidating the entire query, but I'm hoping that someone can help me understand why something is not working.
This solution works, by just blowing away the entire related cache:
function useManuallyAddMessage() {
const queryClient = useQueryClient();
const manuallyAddMessage = React.useCallback(
(message: Message) => {
queryClient.invalidateQueries([
messagesCacheKey,
{ conversationId: message.conversationId },
]);
},
[queryClient],
);
return { manuallyAddMessage };
}
This solution which just adds the message manually does not work, despite it seeming like it should:
function useManuallyAddMessage() {
const queryClient = useQueryClient();
const manuallyAddMessage = React.useCallback(
(message: Message) => {
queryClient.setQueryData<InfiniteData<MessagePage>>(
[messagesCacheKey, { conversationId: message.conversationId }],
oldData => {
if (oldData === undefined) {
return undefined;
}
const [firstPage, ...rest] = oldData?.pages;
firstPage.messages.unshift(message);
return {
...oldData,
pages: [{ ...firstPage }, ...rest],
};
},
);
},
[queryClient],
);
return { manuallyAddMessage };
}
I've tried everything to try and get the cache to update on the consumed components. I've watched a subscription to queryCache send events to an observer but there doesn't seem to be an obvious reason why the cache is not updating.
Upvotes: 0
Views: 2235
Reputation: 28903
Please don't mutate data in the cache, but always make updates fully immutable. Especially:
firstPage.messages.unshift(message);
directly mutates the messages array. If you prefer the mutable syntax, use something like immer
to help.
Upvotes: 2