使用 Apollo React 客户端,为什么您不总是需要解析器来解析 @client GraphQL 查询?

With Apollo React client, why you not always need a resolver to resolve @client GraphQL queries?

我正在学习如何使用 Apollo Client for React 以及如何使用缓存管理本地状态。从 docs 开始,它就像使用 cache.writeData 写入缓存并使用简单查询从中读取一样简单。他们的例子是

const GET_VISIBILITY_FILTER = gql`
  {
    visibilityFilter @client
  }
`;

然后我将我的 JSX 包装在一个查询中,并且可以很好地读取值(在我的例子中 loggedIn

 return <Query query={GET_LOGGED_IN}>
      {({loading, error, data}) => {

        const {loggedIn} = data

不过,我很好奇,为什么我不需要为此编写解析器来工作。是因为对于标量值,如果一个值存在于对象的根部,也就是说,在缓存的顶层,Apollo/GraphQL 会自动获取该值并在没有解析器的情况下将其发送给您?

这有什么限制,也就是说,您可以在不编写解析器的情况下在根级别获取数组吗?对象?我假设不会,as these don't seem to be scalars。但如果数据是硬编码的,即不需要任何数据库查找,答案仍然是否定的?

来自the docs

[The @client directive] tells Apollo Client to fetch the field data locally (either from the cache or using a local resolver), instead of sending it to our GraphQL server.

如果指令存在于某个字段上,Apollo 将尝试使用提供的解析器解析该字段,或者如果缓存不存在则直接从缓存中获取。您可以在根级别使用几乎任何类型的数据初始化缓存(注意包含对象的 __typename 字段),并且您应该能够获取它而不必同时提供 resolver它。另一方面,提供解析器可以让您更精细地控制实际从缓存中获取的内容——即您可以使用项目数组初始化缓存,但使用解析器来提供过滤或排序它们的方法。

这里有一个重要的细微差别:在没有解析器的情况下获取 仅当缓存中有数据要获取时 才有效。这就是为什么在构建客户端时为这些字段提供初始状态很重要。如果您有一个嵌套更深的 @client 字段(例如,您可能在从服务器获取的数据旁边包含其他信息),从技术上讲,您也不必编写解析器。但是我们通常会写它们,因为缓存中没有这些嵌套字段的现有数据。

除了 Daniel 的出色(一如既往)回答外,我还想补充几句。

您可以使用 (read/write) 个对象来直接缓存和操作其属性。

对本地数据使用解析器和突变有助于提高可读性、数据 access/change 统一性、整体可管理性或未来更改(将 feature/settings 移至服务器)。

您可以在 apollo-universal-starter-kit 项目中找到更多 practical/advanced 本地状态管理示例。