Ryan Pfister
Ryan Pfister

Reputation: 3276

Infinite query not updating after setQueryData

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

Answers (1)

TkDodo
TkDodo

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

Related Questions