当查询待处理时,Apollo optimistResponse 未应用

发布于 2025-01-09 20:56:59 字数 829 浏览 0 评论 0原文

如果在执行带有 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
     }
  }
});

最小的codesandbox.io示例 。人为添加了1秒的延迟环节,让效果更加明显。

直接缓存写入似乎也会发生相同的行为;如果存在挂起的读取查询,写入不会导致重新渲染。 如果使用突变批处理查询,也可以看到相同的行为。

这是预期的行为吗?如果是这样,有没有办法绕过它?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

始于初秋 2025-01-16 20:56:59

Apollo useQuery 挂钩使用默认的 cache-first 获取策略。在内部,当 Apollo 缓存更新时,会发生以下情况

  1. 检查是否有任何查询正在观察缓存的该部分
  2. 检查是否应通知它们更新
  3. 通知

当检查是否通知查询时,会检查查询当前是否为正在飞往服务器,如果是这样,仅在 fetch-policy 为 仅缓存缓存和网络

这很好,而且很有意义,当您知道数据即将更新时,您不想花费 CPU 重新渲染。

这会导致上例中出现问题,因为应用乐观更新时正在执行refetch查询。 shouldNotify 检查将返回 false。更改查询获取策略可以解决此问题

const {data, refetch} = useQuery(GET_TODOS, {
   fetchPolicy: 'cache-and-network'
});

The Apollo useQuery hook uses a default fetch-policy of cache-first. Internally when the Apollo cache is updated the following occurs

  1. Check if any queries are observing that part of the cache
  2. Check if they should be notified of the update
  3. Notify

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'
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文