Reputation: 1426
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
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
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