【问题标题】:Does Apollo client optimistic update changes reference for every list item?Apollo 客户端是否乐观更新更改每个列表项的参考?
【发布时间】:2024-04-22 05:15:02
【问题描述】:
  1. 我有父组件 A,我从中获取 TODO 列表 (比如说 10 项),然后映射这个数组并将整个对象传递给组件 B

  2. 组件 B 有一个 memo 包装器来比较 todo 对象引用以重新渲染仅更新的组件。某样东西:

    export default memo(ComponentB, (prevProps, nextProps) => {  
     return prevProps.TODO === nextProps.TODO
    })
    
  3. 从组件 B 上的按钮单击调用 useMutation 以在列表中添加一项。我提供了 optimisticResponseupdate 功能,就像在 Apollo doc

    上一样
  4. 一切正常,除了:当我添加 optimisticResponse 以快速更改 UI 并登录组件 B 时,我看到每个列表项都在重新渲染,但是,如果我只是离开 update 函数而没有 optimisticResponse,那么我会看到只有一项重新渲染。

所以我的问题是,Apollo 是这样处理 optimisticResponse 更新的,还是我应该继续在我的代码中寻找一些问题,并且我已经在尝试找出几个小时了: /

我只是找不到任何材料来指出这种特殊情况,如果有人知道答案,也许可以分享链接或小建议。谢谢!

【问题讨论】:

    标签: reactjs react-apollo apollo-client


    【解决方案1】:

    乐观响应被提交到缓存,所以你的逻辑会“认为”数据已经更新。服务器响应后,恢复缓存并应用真实数据。因此,实际上,您可能会体验到 2 次更新,而您原本预计只有 1 次更新。

    除此之外,我相信您是说您为每个“TODO”项目呈现了一个组件。 AKA,您没有将数组传递给单个组件。这听起来像是正确的方法,只要确保这是你所拥有的。那为什么他们都更新了?您似乎不需要担心这个问题的阿波罗代码。我认为第一步是换行,

    return prevProps.TODO === nextProps.TODO
    

    做一个不依赖于参考的比较。相反,最简单的快速更改是 TODO 上有一些字符串 ID 字段。在这种情况下,你可以这样做,

    return prevProps.TODO.id === nextProps.TODO.id
    

    这样您就不必担心 apollo 返回的是相同的引用还是具有相同数据的新对象。如果这不能解决问题,请在 cmets 中告诉我,我们可以继续寻找。

    【讨论】:

    • 感谢您的宝贵时间!是的,当然,如果我只比较一个字段,假设您提到的 ID 只会重新渲染新字段,但是比较对象引用会更有意义,因为如果您需要更新 TODO 对象中的一个字段,那么它意味着我必须在备忘录功能中增加单独的字段检查,它可能会越来越大。这就是为什么我想知道 Apollo 在使用乐观响应时是否会更改每个 TODO 对象引用,因为如果没有乐观响应,它只会重新渲染更改的组件。