Apollo 客户端乐观更新是否更改每个列表项的引用?

Van*_*ano 5 reactjs react-apollo apollo-client

  1. 我有父组件A从中获取 TODO 列表(假设有 10 个项目),然后映射此数组并将整个对象传递给组件B

  2. 组件B有一个备忘录包装器来比较todo对象引用以仅重新渲染更新的组件。喜欢:

    export default memo(ComponentB, (prevProps, nextProps) => {  
     return prevProps.TODO === nextProps.TODO
    })
    
    Run Code Online (Sandbox Code Playgroud)
  3. 从组件B上的按钮单击调用useMutation以在列表中添加一项。我在Apollo doc上提供了乐观响应更新功能

  4. 一切正常,除了:当我为快速 UI 更改添加optimizeResponse并在组件B 中登录时,我看到每个列表项都在重新渲染,但是如果我只保留更新功能而没有optimizeResponse那么我看到只有一个项目重新渲染- 渲染。

所以我的问题是,Apollo是如何处理乐观响应更新的,还是我应该继续在我的代码中寻找一些问题,并且我已经在尝试计算小时数了:/

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

Nic*_*der 1

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

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

return prevProps.TODO === nextProps.TODO
Run Code Online (Sandbox Code Playgroud)

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

return prevProps.TODO.id === nextProps.TODO.id
Run Code Online (Sandbox Code Playgroud)

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