If you have a pending query when a mutation with an optimisticResponse
is executed, the optimisticResponse
doesn’t get applied.
const {data, refetch} = useQuery(GET_TODOS);
const [updateTodo] = useMutation(UPDATE_TODO);
// in a form submit handler:
refetch();
// Immediately mutate while the _query_ is pending
updateTodo({
variables: { id, description: description + 1},
optimisticResponse: {
updateTodo: {
id,
__typename: "Todo",
description: description + 1
}
}
});
Minimal codesandbox.io example. There’s an artificial 1 second delay link added to make the effect more obvious.
The same behaviour appears to occur with direct cache writes as well; writes will not cause a re-render if there is a pending read query.
The same behaviour can also be witnessed if batching
a query in with a mutation.
Is this the intended behaviour? And if so, is there a way to bypass it?
The Apollo useQuery
hook uses a default fetch-policy of cache-first
. Internally when the Apollo cache is updated the following occurs
When checking whether to notify a query, there is a check to see if the query is currently in flight to the server and if so only notify when the fetch-policy is cache-only
or cache-and-network
.
This is fine, and makes sense, you don't want to spend CPU re-rendering when you know the data is just about to update.
This causes a problem in the example above due to the refetch
query being in progress when the optimistic update is applied. The shouldNotify
check will return false. Changing the queries fetch policy fixes this
const {data, refetch} = useQuery(GET_TODOS, {
fetchPolicy: 'cache-and-network'
});