寻求帮助了解 Apollo Client 本地状态和缓存

Posted

技术标签:

【中文标题】寻求帮助了解 Apollo Client 本地状态和缓存【英文标题】:Looking for help understanding Apollo Client local state and cache 【发布时间】:2019-09-24 05:34:09 【问题描述】:

我正在使用 Apollo Client 本地状态和缓存,虽然我已经阅读了文档 (https://www.apollographql.com/docs/react/essentials/local-state)、一些教程(例如,https://www.robinwieruch.de/react-apollo-link-state-tutorial/)并查看了一些示例,但我有点糊涂。除了您可能针对以下具体问题提供的任何见解之外,我们将非常感谢您提供任何指向其他优秀文档/资源的链接,以便将事情放在上下文中。

特别是,我了解如何存储和检索本地客户端数据,但我没有看到事物如何与从服务器检索和发送回服务器的数据集成。

以简单的“待办事项应用”为起点,我有几个问题。

1) 如果您使用查询从服务器下载一组数据(在本例中为“todos”),缓存数据与服务器端数据之间的关系是什么?也就是说,我通过查询获取数据,它会自动存储在缓存中。现在,如果我想在本地获取该数据,并修改它(在这种情况下,添加待办事项或修改它),我该怎么做?我知道如何处理我创建的数据,但不知道我下载的数据,例如,在这种情况下,我的待办事项集。例如,有些教程引用了__typename——如果是从服务器下载的数据,这个__typename是什么?如果我使用readQuery 来获取从服务器下载并存储在缓存中的数据,我会使用什么查询?和我原来下载数据的一样吗?

2) 一旦我修改了这个本地数据(例如,在 todos 的情况下,将一个 todo 设置为“完成”),并使用writeData 将其写回缓存,它是如何被发回的到服务器,使本地副本和远程副本同步?有突变?所以我负责将副本存储到本地缓存通过两个单独的操作将其发送到服务器?

3) 据我了解,除非您另有说明,否则如果您从 Apollo Client 进行查询,它将首先检查您请求的数据是否在缓存中,否则它将调用服务器。那么,为什么你需要在example code 中创建一个@client 来满足待办事项呢?因为这些不是通过事先查询从服务器下载的,而只是本地数据?

const GET_TODOS = gql`
  
    todos @client 
      id
      completed
      text
    
    visibilityFilter @client
  
`;

如果它们实际上是使用较早的查询下载的,您不能只使用最初用于从服务器获取数据的相同查询,而不是放入@client,并且如果数据在缓存中,你会得到缓存的数据吗?

4) 最后,我读到 Apollo 客户端会“自动更新”——也就是说,如果您将修改后的数据发送到服务器(例如,在我们的例子中是修改后的待办事项),Apollo 客户端将确保一条数据在缓存中被修改,通过 ID 引用它。有什么规定什么时候做,什么时候不做?如果 Apollo 客户端使用 ID 与服务器保持同步,我们什么时候需要像上面一样“手动”处理它,什么时候不需要?

感谢您提供任何见解,如果您有指向上述文档以外的其他文档的链接,或者一个好的教程,我将不胜感激

【问题讨论】:

【参考方案1】:

    __typename 是 Apollo 内置的自动魔术方式,用于跟踪和缓存查询结果。默认情况下,您可以使用项目的__typenameid 在缓存中查找项目。在您手动调整缓存之前,您通常不需要担心__typename。在大多数情况下,只需在原始请求之后重新运行服务器查询以从缓存中提取。服务器响应默认是缓存的,所以下次运行查询时,它会从缓存中拉取。

    这取决于您的情况,但大多数情况下,如果您正确设置 ID,Apollo 客户端将自动同步来自突变的更改。您需要做的就是返回id 属性和变异查询中任何更改的字段,Apollo 将自动更新缓存。因此,如果您描述将待办事项标记为已完成的位置,您可能应该只将突变发送到服务器,然后在突变响应中请求完成的字段和 id。客户端会自动更新。

    您可以使用原始查询。 Apollo 客户端本质上使用 query + variable -> results 映射缓存内容。只要您使用相同的变量提交相同的查询,它就会从缓存中提取(除非您明确告诉它不要这样做)。

    请参阅我对上面 #2 的回答,但只要您在突变中包含 id 和任何修改过的数据,Apollo 客户端就会为您处理它。如果您添加新数据,例如将待办事项添加到列表,它不会为您处理。删除数据也是如此。

【讨论】:

以上是关于寻求帮助了解 Apollo Client 本地状态和缓存的主要内容,如果未能解决你的问题,请参考以下文章

useMutation 不改变本地状态

Apollo Client 2.1 中的突变错误处理

Apollo 链路状态默认解析器不工作(@client 查询参数变量)

登录状态不会在 React、Apollo Client 2、Graphcool 中被动更新

将组件状态与 Apollo 本地状态绑定

apollo client 获取meta url 为服务器内网地址