在了解Apollo客户端本地状态和缓存方面寻求帮助

时间:2019-05-06 14:51:11

标签: caching apollo react-apollo apollo-client

我正在使用Apollo Client的本地状态和缓存,尽管我已经阅读了文档(https://www.apollographql.com/docs/react/essentials/local-state),但是有一些教程(例如https://www.robinwieruch.de/react-apollo-link-state-tutorial/)并查看了一些示例,我有点困惑。除了可以为您提供以下特定问题的任何见解之外,任何与其他有用的其他文档/资源的链接都将非常有用。

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

以简单的“ todo应用程序”为起点,我有两个问题。

1)如果使用查询从服务器下载一组数据(在本例中为“ todos”),则缓存的数据与服务器端数据之间的关系是什么?也就是说,我通过查询获取数据,并将其自动存储在缓存中。现在,如果我想在本地获取该数据并进行修改(在这种情况下,添加待办事项或对其进行修改),我该怎么做?我知道如何针对已创建的数据执行此操作,但对于已下载的数据(例如本例中的待办事项)不执行此操作。例如,某些教程引用了__typename -如果从服务器下载了数据,那么__typename会是什么?而且,如果我使用readQuery来抓取从服务器下载并存储在缓存中的数据,那我将使用什么查询?我原来用来下载数据的一样吗?

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

3)据我了解,除非另行指定,否则如果您从Apollo Client进行查询,它将首先检查您请求的数据是否在缓存中,否则它将调用服务器。那么,为什么需要在example code中创建@client才能完成任务呢?因为这些不是通过事先查询从服务器下载的,而是仅是本地数据?

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

如果实际上是使用较早的查询下载的,则不能只使用最初用于从服务器获取数据的查询,而不要使用@client,并且数据是否位于服务器中。缓存,您会得到缓存的数据吗?

4)最后,我读到Apollo Client将自动更新内容-也就是说,如果您将修改后的数据发送到服务器(例如,在我们的示例中是修改后的待办事项),Apollo Client将确保在缓存中修改数据,并通过ID对其进行引用。关于何时以及何时不存在任何规则?如果Apollo Client使用ID使服务器与服务器保持同步,那么如上所述,我们何时需要“手动”处理它,何时不使用?

感谢您的见解,如果您有除上述文档之外的其他文档的链接,或者是一个很好的教程,我将不胜感激

1 个答案:

答案 0 :(得分:0)

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

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

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

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