T
TanStack2w ago
sunny-green

context.client undefined in react query V5

The docs indicate that the onMutate option in the useMutation hook should be a context item that contains the query client. That would then allow us to use something like context.client.setQueryDate without calling queryClient = useQueryClient().
onMutate: async (updatedFailureMode) => {
await queryClient.cancelQueries({
queryKey: ["dfmea-data", projectId],
});
const previousData = queryClient.getQueryData(["dfmea-data", projectId]);
queryClient.setQueryData(["dfmea-data", projectId], (oldData) => {
return oldData.map((item) =>
item.failureModeId === updatedFailureMode.failureModeId
? updatedFailureMode
: item
);
});
return { previousData };
},
onMutate: async (updatedFailureMode) => {
await queryClient.cancelQueries({
queryKey: ["dfmea-data", projectId],
});
const previousData = queryClient.getQueryData(["dfmea-data", projectId]);
queryClient.setQueryData(["dfmea-data", projectId], (oldData) => {
return oldData.map((item) =>
item.failureModeId === updatedFailureMode.failureModeId
? updatedFailureMode
: item
);
});
return { previousData };
},
For example, I would love to instead of the above do something like:
onMutate: async (updatedFailureMode, context) => {
await context.client.cancelQueries({
queryKey: ["dfmea-data", projectId],
});
const previousData = context.client.getQueryData(["dfmea-data", projectId]);
context.client.setQueryData(["dfmea-data", projectId], (oldData) => {
return oldData.map((item) =>
item.failureModeId === updatedFailureMode.failureModeId
? updatedFailureMode
: item
);
});
return { previousData };
},
onMutate: async (updatedFailureMode, context) => {
await context.client.cancelQueries({
queryKey: ["dfmea-data", projectId],
});
const previousData = context.client.getQueryData(["dfmea-data", projectId]);
context.client.setQueryData(["dfmea-data", projectId], (oldData) => {
return oldData.map((item) =>
item.failureModeId === updatedFailureMode.failureModeId
? updatedFailureMode
: item
);
});
return { previousData };
},
The docs say this should work but I get an error saying context.client does not exist. https://tanstack.com/query/latest/docs/framework/react/guides/mutations
Mutations | TanStack Query React Docs
Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects. For this purpose, TanStack Query exports a useMutation hook. Here's an example of a mutation t...
5 Replies
sunny-green
sunny-greenOP2w ago
I don't think the answer to that is right. If you look at the v5 docs, it is very clear onMutateResult is the context that comes out of the onMutate function, not context. this is slightly confusing because it used to be context. Here is the side effect documentation for v5, showing onMutateResult is diff than context:
useMutation({
mutationFn: addTodo,
onSuccess: (data, variables, onMutateResult, context) => {
// I will fire first
},
onError: (error, variables, onMutateResult, context) => {
// I will fire first
},
onSettled: (data, error, variables, onMutateResult, context) => {
// I will fire first
},
})

mutate(todo, {
onSuccess: (data, variables, onMutateResult, context) => {
// I will fire second!
},
onError: (error, variables, onMutateResult, context) => {
// I will fire second!
},
onSettled: (data, error, variables, onMutateResult, context) => {
// I will fire second!
},
})
useMutation({
mutationFn: addTodo,
onSuccess: (data, variables, onMutateResult, context) => {
// I will fire first
},
onError: (error, variables, onMutateResult, context) => {
// I will fire first
},
onSettled: (data, error, variables, onMutateResult, context) => {
// I will fire first
},
})

mutate(todo, {
onSuccess: (data, variables, onMutateResult, context) => {
// I will fire second!
},
onError: (error, variables, onMutateResult, context) => {
// I will fire second!
},
onSettled: (data, error, variables, onMutateResult, context) => {
// I will fire second!
},
})
and here it is from v4, showing that v4 context is the same as onMutateResult (I think), and v5 context is something completely different, supposedly enabling us to get the queryClient context.
useMutation({
mutationFn: addTodo,
onSuccess: (data, variables, context) => {
// I will fire first
},
onError: (error, variables, context) => {
// I will fire first
},
onSettled: (data, error, variables, context) => {
// I will fire first
},
})

mutate(todo, {
onSuccess: (data, variables, context) => {
// I will fire second!
},
onError: (error, variables, context) => {
// I will fire second!
},
onSettled: (data, error, variables, context) => {
// I will fire second!
},
})
useMutation({
mutationFn: addTodo,
onSuccess: (data, variables, context) => {
// I will fire first
},
onError: (error, variables, context) => {
// I will fire first
},
onSettled: (data, error, variables, context) => {
// I will fire first
},
})

mutate(todo, {
onSuccess: (data, variables, context) => {
// I will fire second!
},
onError: (error, variables, context) => {
// I will fire second!
},
onSettled: (data, error, variables, context) => {
// I will fire second!
},
})
equal-aqua
equal-aqua2w ago
onMutate receives variables, mutation, context so it's the 3rd param. I think we just got this wrong in the docs sorry I misread our types. the second param for onMutate should be context. If it's not, please show a minimal, runnable reproduction
adverse-sapphire
adverse-sapphire2w ago
though for "@tanstack/react-query": "^5.67.2" context doesn't exist in onMutate like OP said, so it's probably added in one of the newer versions

Did you find this page helpful?