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

Posted

技术标签:

【中文标题】使用 writeQuery() 更新 Apollo 客户端上的缓存【英文标题】:Updating cache on Apollo Client with writeQuery() 【发布时间】:2021-09-16 23:42:52 【问题描述】:

不是重复的 我一直在查看documentations,并阅读了很多关于类似问题的信息,但我没有找到答案。

问题:我没有从 console.log() 中的 writeQuery 得到任何响应,并且在突变完成后缓存没有更新。除了 cache.writeQuery() 的结果之外,我能够记录所有内容,但是我无法弄清楚。有人能指出我哪里出了问题以及如何解决吗?

我尝试做的事情: 从缓存中删除(通过突变)删除的对象,方法是用删除对象的新数据替换以前的数据。并保存更新的缓存!

productCategorie 查询:

const GET_CATEGORIES_AND_PRODUCTS = gql`
    query GetProductcategories($site_id: ID!, $first: Int!, $page: Int!, $orderBy: [OrderByClause!])
        productcategories(site_id: $site_id, first: $first, page: $page, orderBy: $orderBy )
            paginatorInfo
                count
                total
            
            data 
            name
            categorie_id
            
        
    
`

CACHE productcategories 查询:

$ROOT_QUERY.productcategories("first":10,"orderBy":["field":"categorie_id","order":"DESC"],"page":1,"site_id":"152")
paginatorInfo:  4 keys
data:  10 keys
  0:  4 keys
     type:"id"
     generated:true
     id:"$ROOT_QUERY.productcategories("first":10,"orderBy": 
["field":"categorie_id","order":"DESC"],"page":1,"site_id":"152").data.0"
     typename:"ProductCategory"
  1:  4 keys
  2:  4 keys
  3:  4 keys
  4:  4 keys
  5:  4 keys
  6:  4 keys
  7:  4 keys
  8:  4 keys
  9:  4 keys
__typename:"ProductCategoryPaginator"

deleteCategorie 突变:

const [deleteCategorie,  loading, error ] = useMutation(DELETE_CATEGORIE, 
            update: (cache, deleteCategorie) => 
                const idToRemove = deleteCategorie.data.deleteCategorie.categorie_id;
                const existingData = cache.readQuery( 
                    query: GET_CATEGORIES_AND_PRODUCTS, 
                    variables:  
                        site_id: localStorage.getItem("site_id"),
                        page: (page + 1),
                        first: rowsPerPage,
                        orderBy: [order],
                  , );
                const deletedObject = existingData.productcategories.data.find((t) => (t.categorie_id === idToRemove));
                const newCats = existingData.productcategories.data.filter((t) => (t.categorie_id !== idToRemove));
                console.log(cache.writeQuery(
                    query: GET_CATEGORIES_AND_PRODUCTS,
                    variables:  
                        site_id: localStorage.getItem("site_id"),
                        page: (page + 1),
                        first: rowsPerPage,
                        orderBy: [order],
                    ,
                    data: 
                        productcategories: 
                            data: [
                                ...newCats
                            ]
                        
                    
                ));
            
        );

欢迎任何帮助,这是我第一次尝试更新缓存!

【问题讨论】:

您尝试过记录 newCats 吗?是否真的从列表中删除了已删除的类别? @mfurkangok,感谢您的回复。我已经成功记录了 newCats 并且它具有预期的 9 个剩余对象。除了 cache.writeQuery() 的结果之外,我能够记录所有内容。 【参考方案1】:

我解决了这个问题。我必须在 typePolicies 中为 ProductCategory 添加一个 keyField,因为它正在寻找这些对象没有的“id”。

我还有一些像 @apollo/react-hooks 这样的旧包,它们以某种方式干预了缓存。有关更多信息,请在 de docs 中查找 updating help。

cache: new InMemoryCache(
        typePolicies: 
            ProductCategory: 
                keyFields: ['categorie_id']
            ,
        ,
   )

更多关于缓存的信息和更多关于缓存的信息可以在其中一个 apollo 博客中找到: https://www.apollographql.com/blog/apollo-client/caching/demystifying-cache-normalization/

【讨论】:

以上是关于使用 writeQuery() 更新 Apollo 客户端上的缓存的主要内容,如果未能解决你的问题,请参考以下文章

Apollo useQuery 钩子不会使用 writeQuery() 方法从缓存中获取更新。没有看到错误

Apollo 客户端 writeQuery 更新存储,但 UI 组件仅在第二次函数调用后更新

在 Apollo-client 中,writeQuery 会更新缓存,但 UI 组件不会重新渲染

变异后的Apollo缓存未更新

更新 apollo 缓存而不调用 graphql 服务器(apollo v3.3)

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