HuolalaTech / react-query-kit

🕊️ A toolkit for ReactQuery that make ReactQuery hooks reusable and typesafe
MIT License
334 stars 11 forks source link

What is the best practice for invalidating queries in react-query-kit #62

Open inceenes10 opened 2 months ago

inceenes10 commented 2 months ago

I generally use the approach in the code below.

import { queryClient } from "@sustable/system";

export const useDeleteUserMutation = createMutation({
    mutationKey: ["corporate", "user", "delete"],
    mutationFn: async (data: IDeleteUserRequest) => {
        await agent.delete("/user/delete", { data });
    },
    onSuccess: () =>
        queryClient.invalidateQueries({
            queryKey: ["corporate", "user", "list"],
        }),
});

This approach does not use useQueryClient() hook and I just wanna know if this approach has any side effect. If there is a side effect, what can I do to prevent that side effect? Is middleware like approach a better solution for this? If it is, could we add this to documentation of react-query-kit

Thank in advance.

liaoliao666 commented 2 months ago

Yeah, you can customize any behavior of this hook via middleware

denisborovikov commented 1 week ago

Here's the middleware I created

const invalidateQueriesAfterMutation = (keys) =>
  (useMutationNext) => {
    return (options) => {
      const queryClient = useQueryClient()

      const onSuccess = (...params) => {
        keys.forEach((key) => {
          if ('guard' in key) {
            if (key.guard(...params)) {
              queryClient.invalidateQueries(key.queryKey)
            }
          } else {
            queryClient.invalidateQueries(key)
          }
        })
        options.onSuccess?.(...params)
      }

      return useMutationNext({ ...options, onSuccess })
    }
  }

Then it can be used:

use: [invalidateQueriesAfterMutation([useFooHook.getKey(), useBarHook.getKey()])],

If you need to invalidate the query conditionally, based on the respond, then use the guard function. If the guard function returns true, the query with the given key is invalidated.

  use: [
    invalidateQueriesAfterMutation([
      {
        guard: (data) => data.foobar === 'baz'
        queryKey: useBazHook.getKey(),
      },
    ])

If your queries are created with RQK, it provides getKey() method to retrieve the query key instead of using the hardcoded string.