Search code examples
reactjsreact-query

How do I update a single record in react-query outside of mutation?


I'm trying to use a function to update a cached react-query following this example using a websocket message.

I was trying something like this:

useSubscription('/queue/..', message => {
        const id = JSON.parse(message.body).itemId;
        queryClient.setQueryData(['items', { id: id }], JSON.parse(message.body));
});

However, this has no effect at all on the cache and the specific item being updated. My expectation is a real-time update once the message is received. The original cache is built elsewhere using useQuery() as follows:

...
const { isLoading, isError, data, error } = useQuery(['items'], fetchItems);

How can I make this work?


Solution

  • Shouldn't the QueryKeys array match what you are using in the useQuery?

    So when calling setQueryData it should be called with the same key: ['items'] and not ['items', { id: id }]

    ['items', { id: id }] is a different query than ['items'] so ['items'] will not be invalidated when you update data for ['items', { id: id }].

    For an example, see https://tkdodo.eu/blog/effective-react-query-keys

    function useUpdateTitle() {
      return useMutation({
        mutationFn: updateTitle,
        onSuccess: (newTodo) => {
          // ✅ update the todo detail
          queryClient.setQueryData(['todos', 'detail', newTodo.id], newTodo)
    
          // ✅ update all the lists that contain this todo
          queryClient.setQueriesData(['todos', 'list'], (previous) =>
            previous.map((todo) => (todo.id === newTodo.id ? newtodo : todo))
          )
        },
      })
    }