Ognjen Mišić
Ognjen Mišić

Reputation: 1426

React Query: parallel loaders / spinners through one useMutation

I have a usecase where I want to mutate the same entity with different keys (ids) in parallel. My question is: is it possible to have separate loaders for every request (react-query cache key) using the same useMutation? Simplified example below (also interactable on codesandbox):

const useUserMutation = (userData) => {
  return useMutation({
    mutationKey: [userData.userName, userData.job], // how to have separate loaders based on mutation keys?
    mutationFn: async ({ user }) => {
      return await axios.post("https://reqres.in/api/users", data);
    }
  });
};

Component body (the userData in state is really irrelevant there, makes no difference whether we store the "clicked" user in state or just mutate with userData, I've just used it so there's a stable reference to the useMutation mutationKeys)

 const [selectedUser, setSelectedUser] = useState({ userName: "", job: "" });
 const userMutation = useUserMutation(selectedUser);

  const handleClick = (userData) => {
    setSelectedUser(userData);
    userMutation.mutate(userData);
  };

   return (
      <span>parallel mutations:</span>
      {data.map((entry) => (
        <div key={entry.userName}>
          {entry.userName}
          <button onClick={handleClick}>
            post stuff
          </button>
          // how to display the spinner only for the user that is currently being mutated?
          {userMutation.isLoading && (
            <span>SPINNER</span>
          )}
        </div>
      ))}

Link to codesandbox: https://codesandbox.io/s/kind-germain-n6vd4

Upvotes: 1

Views: 1626

Answers (2)

Ognjen Mišić
Ognjen Mišić

Reputation: 1426

Thanks to @TkDodo, the piece of the puzzle which I was missing is useIsMutating hook together with the mutationKeys on the mutation function. Works like a charm! The final sandbox: https://codesandbox.io/s/sleepy-wood-20nut

Upvotes: 0

TkDodo
TkDodo

Reputation: 29056

I think the easiest way is to create a separate component for each user, then use the mutation inside that component. your sandbox modified: https://codesandbox.io/s/suspicious-moser-tr8h6?file=/src/Home.js

you don't even need a mutationkey for that, and the mutation is close to where it is used (=the button that clicked it)

Upvotes: 1

Related Questions