使用尚不存在的查询从 apollo 缓存中读取查询,但已将所有信息存储在缓存中

Read query from apollo cache with a query that doesn't exist yet, but has all info stored in the cache already

我有一个可以输入此查询的 graphql 端点:

fragment ChildParts {
  id
  __typename
}

fragment ParentParts {
  __typename
  id
    children {
   edges{
       node {
         ...ChildParts 
       }
   }
}

query {
  parents {
    edges
      nodes {
        ...ParentParts
      }
    }
  }
}

执行时,它returns是这样的:

"data": {
  "edges": [
     "node": {
       "id": "<some id for parent>",
       "__typename": "ParentNode",
       "children": {
         "edges": [
           node: {
             "id": "<some id for child>",
             "__typename": "ChildNode"
           },
           ...
         ]
       }
     },
     ...   
  ]
}

现在,有了 apollo 客户端,在突变之后,我可以从缓存中读取这个查询,并更新/添加/删除任何 ParentNode 以及任何 ChildNode,但我必须检查这个查询返回的结构.

现在,我正在寻找从缓存中获取 ChildNodes 列表的可能性(已经有那些,因为缓存是作为平面列表创建的),以便稍微更新嵌套数据更轻松。是否有可能从缓存中读取查询,而无需之前从服务器读取相同的查询?

您可以使用客户端的 readFragment 方法从缓存中检索任何一项。这只需要 id 和片段字符串。

const todo = client.readFragment({
  id,
  fragment: gql`
    fragment fooFragment on Foo {
      id
      bar
      qax
    }
  `,
})

注意这里的id是dataIdFromObject函数返回的缓存键——如果你没有指定自定义函数,那么(前提是__typename和id或_id字段存在) 默认实现只是:

${result.__typename}:${result.id || result._id}

如果您提供了自己的 dataIdFromObject 函数,则需要提供该函数返回的任何 ID。

正如@Herku 指出的那样,根据用例,还可以使用缓存重定向在解析另一个查询时利用为一个查询缓存的数据。这是作为设置 InMemoryCache:

的一部分配置的
const cache = new InMemoryCache({
  cacheRedirects: {
    Query: {
      book: (_, args, { getCacheKey }) =>
        getCacheKey({ __typename: 'Book', id: args.id })
    },
  },
})

不幸的是,在撰写此答案时,我认为没有任何方法可以通过 ID 删除缓存项。正在进行讨论 here around that point (original issue here)。