The only thing that can stop a function from running is that function itself. So if you want the mutationFn to stop partway through, add code something like this:
const isCancelled = useRef(false);
useMutation({
mutationFn: async () => {
isCancelled.current = false;
await firstTask()
// If you prefer, you could throw an error instead of returning
if (isCancelled.current) return;
await secondTask()
if (isCancelled.current) return;
await thirdTask()
},
...
})
...
<button onClick={() => { isCancelled.current = true }}/>
I know I can't cancel the individual tasks once they are in-flight
That's mostly true, but i want to point out that if the tasks are making fetch requests, fetch supports abort signals. So if that's something you want to do, then instead of storing a boolean isCancelled you can store an AbortController
const controller = useRef(null)
useMutation({
mutationFn: async () => {
controller.current = new AbortController();
const signal = controller.current.signal
await firstTask(signal); // change this code to use the signal
if (signal.aborted) return;
await secondTask(signal);
if (signal.aborted) return;
await thirdTask(signal);
},
...
})
...
<button onClick={() => { controller.current?.abort() }}/>