New onQuery handler? #278
-
In some cases, we might want to optimistically update the cache before or at the same time, when the mutation occurs. We can do it by using queryCache.setQueryData('todos', [...data, text])
...
mutatePostTodo(text) But as I can see, we can't encapsulate an optimistic cache update into the custom hook. If we would have a handler, that executes at the same time as the mutation, we could do it: function useCustomDelete() {
return useMutation(foo, { onQuery: variables => queryCache.setQueryData(...)})
}
const [delete] = useCustomDelete();
...
delete(variables); What do you think? |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 20 replies
-
Ooooooo very interesting. How about onMutate? |
Beta Was this translation helpful? Give feedback.
-
Would it be worth discussing how a general rollback would take place too? Eg if the mutation falls? |
Beta Was this translation helpful? Give feedback.
-
What do you think about this? Automatic Rollback for Failed MutationsWhen you optimistically update your state before performing a mutation, there is a non-zero chance that the mutation will fail. In that event, you would normally refetch your queries that you optimistically updated. In some circumstances though, refetching may not work correctly and the mutation error could represent some type of server issue that won't make it possible to refetch. In this event, you can instead choose to rollback your update. To do this, useMutation(updateTodo, {
onMutate: (newTodo) => {
// Store the previous value in this closure
const previousTodo = queryCache.getQueryData(['todos', newTodo.id])
// Optimistically update the query data
queryCache.setQueryData(['todos', newTodo.id], newTodo)
// Return a rollback function
return (err) => {
queryCache.setQueryData(['todos', newTodo.id], previousTodo)
}
}
}) |
Beta Was this translation helpful? Give feedback.
-
Did you consider something like this? function useCustomDelete() {
const [mutate, ...mutation] = useMutation(foo);
function customMutate(...args) {
queryCache.setQueryData(...)
return mutate(...args)
}
return [customMutate, ...mutation];
}
const [delete] = useCustomDelete();
...
delete(variables); |
Beta Was this translation helpful? Give feedback.
-
Here are the final docs: Automatic Rollback for Failed MutationsWhen you optimistically update your state before performing a mutation, there is a non-zero chance that the mutation will fail. In most cases, you can just trigger a refetch for your optimistic queries to revert them to their true server state. In some circumstances though, refetching may not work correctly and the mutation error could represent some type of server issue that won't make it possible to refetch. In this event, you can instead choose to rollback your update. To do this, useMutation(updateTodo, {
// When mutate is called:
onMutate: (newTodo) => {
// Snapshot the previous value
const previousTodo = queryCache.getQueryData(['todos', newTodo.id])
// Optimistically update to the new value
queryCache.setQueryData(['todos', newTodo.id], newTodo)
// Return the snapshotted value
return previousTodo
},
// If the mutation fails, use the value returned from onMutate to roll back
onError: (err, newTodo, previousTodo) => {
queryCache.setQueryData(['todos', newTodo.id], previousTodo)
}
// If the mutation was successful:
onSuccess: newTodo => {
queryCache.setQueryData(['todos', newTodo.id], newTodo)
}
}) You can also use the useMutation(updateTodo, {
// ...
onSettled: (newTodo, error, variables, previousTodo) => {
if (error) {
queryCache.setQueryData(['todos', newTodo.id], previousTodo)
} else {
queryCache.setQueryData(['todos', newTodo.id], newTodo)
}
},
}) |
Beta Was this translation helpful? Give feedback.
Here are the final docs:
Automatic Rollback for Failed Mutations
When you optimistically update your state before performing a mutation, there is a non-zero chance that the mutation will fail. In most cases, you can just trigger a refetch for your optimistic queries to revert them to their true server state. In some circumstances though, refetching may not work correctly and the mutation error could represent some type of server issue that won't make it possible to refetch. In this event, you can instead choose to rollback your update.
To do this,
useMutation
'sonMutate
handler option allows you to return a snapshotted rollback value that will later be passed to bothonError
andonSettled
…