查询挂起时未应用 Apollo optimisticResponse
Apollo optimisticResponse not applied when query is pending
如果执行带有 optimisticResponse
的突变时有待处理的查询,则不会应用 optimisticResponse
。
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。人为添加了 1 秒延迟 link 以使效果更明显。
同样的行为似乎也发生在直接缓存写入中;如果有挂起的读取查询,写入不会导致重新呈现。
如果 batching
带有突变的查询也可以看到相同的行为。
这是预期的行为吗?如果是这样,有没有办法绕过它?
Apollo useQuery
挂钩使用 cache-first
的默认 fetch-policy。在内部更新 Apollo 缓存时会发生以下情况
- 检查是否有任何查询正在观察缓存的那部分
- 检查是否应通知他们更新
- 通知
检查是否通知查询时,会检查查询当前是否正在发送到服务器,如果是,则仅在 fetch-policy 为 cache-only
or cache-and-network
时通知。
这很好,而且有道理,当您知道数据即将更新时,您不想花费 CPU re-rendering。
由于在应用乐观更新时正在进行 refetch
查询,这会导致上述示例出现问题。 shouldNotify
检查将 return 错误。更改查询获取策略可以解决此问题
const {data, refetch} = useQuery(GET_TODOS, {
fetchPolicy: 'cache-and-network'
});
如果执行带有 optimisticResponse
的突变时有待处理的查询,则不会应用 optimisticResponse
。
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。人为添加了 1 秒延迟 link 以使效果更明显。
同样的行为似乎也发生在直接缓存写入中;如果有挂起的读取查询,写入不会导致重新呈现。
如果 batching
带有突变的查询也可以看到相同的行为。
这是预期的行为吗?如果是这样,有没有办法绕过它?
Apollo useQuery
挂钩使用 cache-first
的默认 fetch-policy。在内部更新 Apollo 缓存时会发生以下情况
- 检查是否有任何查询正在观察缓存的那部分
- 检查是否应通知他们更新
- 通知
检查是否通知查询时,会检查查询当前是否正在发送到服务器,如果是,则仅在 fetch-policy 为 cache-only
or cache-and-network
时通知。
这很好,而且有道理,当您知道数据即将更新时,您不想花费 CPU re-rendering。
由于在应用乐观更新时正在进行 refetch
查询,这会导致上述示例出现问题。 shouldNotify
检查将 return 错误。更改查询获取策略可以解决此问题
const {data, refetch} = useQuery(GET_TODOS, {
fetchPolicy: 'cache-and-network'
});