为啥“自动商店更新”在反应应用程序的客户端商店中不起作用?

Posted

技术标签:

【中文标题】为啥“自动商店更新”在反应应用程序的客户端商店中不起作用?【英文标题】:Why doesn't `Automatic store updates` work on client side store in react application?为什么“自动商店更新”在反应应用程序的客户端商店中不起作用? 【发布时间】:2019-11-09 23:27:11 【问题描述】:

我正在使用react-apollo 在我的 react 应用程序中管理客户端存储,因此没有后端 graphql 服务器。与apollo 相关的所有内容都在客户端运行。我将所有 UI 状态存储在 ApolloClient 的缓存中。我还在客户端定义了所有解析器。

以下是新建客户端实例的代码:

new ApolloClient(
    cache,
    resolvers: 
      Mutation: 
        ...cartResolvers,
      ,
    ,
    typeDefs: [typeDefs]
  );

我已经阅读了这篇文章https://www.apollographql.com/docs/angular/features/cache-updates/#automatic-store-updates,关于在 apollo graphql 突变和查询中使用 ID 自动更新存储。但这似乎不起作用。我有以下查询和突变:

export const queryCart = gql`
  
    cart @client 
      items 
        id
        name
        price
        quantity
        image
      
    
  
`;

export const addToBasket = gql`
  mutation addToBasket($sku: ID!) 
    addToBasket(id: $sku)  @client 
      items 
        id
        name
        price
        quantity
        image
      
    
  
`;

我已经为该突变addToBasket 定义了解析器。

const addToBasket = (_parent: any, item:  id: string ,  cache : ResolverCacheType): CartProps => 
   ...
   return 
      items: [ id, name, price, quantity, image  ]
   

我发现即使我在解析器中返回id,缓存也没有更新,查询也没有反应。我可以通过cache.writeData 手动更新解析中的缓存数据来使其工作。

【问题讨论】:

【参考方案1】:

您的用例与react-apollo 提供的自动更新场景不同:您运行的突变不会更新项目本身。相反,它会更新一个未以任何方式键入的数组,以便 react-apollo 跟踪其更改。

要利用自动更新功能,您可以将项目数组的数据结构从现在的简单数组更改为类似于此的对象:

 _id, [id, name, price, ...]

查询和突变都应该返回这个对象。然后你就有了与the doc 中的示例相同的设置。变异运行后,返回对象与本地缓存具有相同的_id,因此react-apollo 知道它需要更新缓存数据。

或者,您可以手动使用cache.writeData(如您已经提到的)或使用refetchQueries 来更新购物车项目数组。

【讨论】:

您能否解释更多关于`它更新一个没有以任何方式键入的数组`的信息?如何对阵列进行更改以使自动更新工作? @ZhaoYi 自动更新的工作方式是id(或_id)字段必须存在于您希望更新的对象中。篮子数组没有。 @ZhaoYi 如果您为购物篮数组分配 id,您可以利用自动更新功能。所以用户购物篮中商品的数据将如下所示: id, [ id, name, price ...]。查询和突变都应该返回这个对象。

以上是关于为啥“自动商店更新”在反应应用程序的客户端商店中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 flex 属性在反应样式的组件中不起作用?

为啥 `R` 管道运算符 `|>` 在使用 Shiny 的反应式编程中不起作用?

为啥 kivy 应用程序中不显示下一个屏幕?

为啥代码版本控制器在 erlang 中不起作用?

为啥 heroku 不能在我的反应应用程序中使用代理?

为啥大多数浏览器的预检请求中不包含 TLS 客户端证书?