T
TanStack2mo ago
genetic-orange

"Nesting" mutations?

I've got a core useUpdate which does a mutation and invalidates some queries in the onSuccess. I've got another useArchive which is really just an update, and should do the same invalidations as useUpdate, but then also a few more things (like some other invalidations) in its own onSuccess. But then I've got a third Sidebar component, which uses useArchive in an event handler, and then has its own onSuccess logic (e.g., close the sidebar). Is there anything particularly wrong with defining a "nested" mutation? Something like:
function useUpdate() {
return useMutation({
mutationFn: (foo) => { /* update mutation */ },
onSuccess() { /* post-update stuff */ }
});
}

function useArchive() {
const {mutateAsync: update} = useUpdate();
return useMutation({
mutationFn: (foo) => update(foo),
onSuccess() { /* post-archive stuff */ }
});
}

function Sidebar() {
const {mutate: archive} = useArchive();
const foo = {foo: 'bar'};

const onArchive = () => archive(foo, {
onSuccess() { /* post-event stuff */ }
});

// ...
}
function useUpdate() {
return useMutation({
mutationFn: (foo) => { /* update mutation */ },
onSuccess() { /* post-update stuff */ }
});
}

function useArchive() {
const {mutateAsync: update} = useUpdate();
return useMutation({
mutationFn: (foo) => update(foo),
onSuccess() { /* post-archive stuff */ }
});
}

function Sidebar() {
const {mutate: archive} = useArchive();
const foo = {foo: 'bar'};

const onArchive = () => archive(foo, {
onSuccess() { /* post-event stuff */ }
});

// ...
}
3 Replies
adverse-sapphire
adverse-sapphire2mo ago
Maybe have a base mutationOptions and three different hooks with different overrides. Easier to track the composition of logic.
genetic-orange
genetic-orangeOP2mo ago
I tried that, but I found the resulting type impossible to deal with elegantly. It requires an as type cast, and even then, it is a PITA to satisfy the type checker. It also hardly seems worth it, since the only properties each customized options object has in common are the key and the function.
other-emerald
other-emerald2mo ago
you can use the same useMutation and use the onSuccess callback on mutate() to do additional things that are component specific, but note that they won't run if the component unmounts before the mutation finishes.

Did you find this page helpful?