Apollo 客户端:更新缓存时的 writeFragment 或 readFragment?

Posted

技术标签:

【中文标题】Apollo 客户端:更新缓存时的 writeFragment 或 readFragment?【英文标题】:Apollo Client: writeFragment or readFragment when updating cache? 【发布时间】:2021-04-04 02:55:56 【问题描述】:

在 useMutation 的 update 钩子中,Apollo 的文档建议使用 writeFragment 来获取对新添加对象的内部引用。我觉得这很奇怪,因为该对象已经存在于缓存中。所以我用readFragment 对其进行了测试,果然,它运行良好。在这个用例中是否更倾向于使用writeFragment 而不是readFragment

示例 1:

https://www.apollographql.com/docs/react/data/mutations/#making-all-other-cache-updates

const [addTodo] = useMutation(ADD_TODO, 
    update(cache,  data:  addTodo  ) 
      cache.modify(
        fields: 
          todos(existingTodos = []) 
            const newTodoRef = cache.writeFragment(
              data: addTodo,
              fragment: gql`
                fragment NewTodo on Todo 
                  id
                  type
                
              `
            );
            return [...existingTodos, newTodoRef];
          
        
      );

摘自该页面:

在 cache.writeFragment 的帮助下,我们得到了一个内部引用 添加的 todo,然后将该引用存储在 ROOT_QUERY.todos 数组。

示例 2:

https://www.apollographql.com/docs/react/caching/cache-interaction/#example-updating-the-cache-after-a-mutation

const [addComment] = useMutation(ADD_COMMENT, 
  update(cache,  data:  addComment  ) 
    cache.modify(
      fields: 
        comments(existingCommentRefs = [],  readField ) 
          const newCommentRef = cache.writeFragment(
            data: addComment,
            fragment: gql`
              fragment NewComment on Comment 
                id
                text
              
            `
          );
          return [...existingCommentRefs, newCommentRef];
        
      
    );
  
);

摘自该页面:

评论已被 useMutation 添加到缓存中。 因此,cache.writeFragment 返回对现有的引用 对象。

我也在 Apollo Client 的讨论区 (https://github.com/apollographql/apollo-client/discussions/7515) 上发布了这个问题,但没有得到回复。

【问题讨论】:

【参考方案1】:

这里解释了从缓存中获取项目时使用writeFragment 而不是readFragment 的好处(摘自https://www.apollographql.com/docs/react/caching/cache-interaction/#example-updating-the-cache-after-a-mutation):

如果您使用缓存能够识别的 options.data 对象调用 writeFragment,根据其 __typename 和主键字段,您可以避免将 options.id 传递给 writeFragment。

无论您是显式提供 options.id 还是让 writeFragment 使用 options.data 来计算,writeFragment 都会返回对已识别对象的引用。

这种行为使 writeFragment 成为获取对缓存中现有对象的引用的好工具,它可以派上用场 为 useMutation 编写更新函数时

这是违反直觉的,因为名称 writeFragment 暗示它用于写入缓存而不是从中读取,但它似乎是推荐的最佳做法。

【讨论】:

以上是关于Apollo 客户端:更新缓存时的 writeFragment 或 readFragment?的主要内容,如果未能解决你的问题,请参考以下文章

在 Apollo 客户端上更新缓存

Apollo 客户端:缓存更新后组件不呈现(反应变量)

轮询不工作时更新 Apollo 客户端 3 的缓存

使用 writeQuery() 更新 Apollo 客户端上的缓存

ReactJS:Apollo graphql 客户端。缓存不在本地更新

查询后如何更新 Apollo 缓存?