如何在 apollo-link-state 中标准化状态?

Posted

技术标签:

【中文标题】如何在 apollo-link-state 中标准化状态?【英文标题】:How to normalize state in apollo-link-state? 【发布时间】:2019-02-13 00:48:05 【问题描述】:

给定一个返回多个级别响应的查询,例如Github's GraphQL API 上的此查询:

query 
  viewer 
    starredRepositories(first: 100) 
      edges 
        node 
          repositoryTopics(first: 100) 
            edges 
              node 
                id
                topic 
                  id
                  name
                
              
            
          
        
      
    
  

如何规范化主题并使用apollo-link-state 将其存储到存储中?


  topics: [Topic]

目前我的店铺设置如下:

import  InMemoryCache  from 'apollo-cache-inmemory';
import  ApolloClient  from 'apollo-client';
import  ApolloLink  from 'apollo-link';
import  withClientState  from 'apollo-link-state';

const cache = new InMemoryCache();

const store = withClientState(
  cache,
  defaults: 
    topics: [],
  ,
  resolvers: ,
  typeDefs: `
    type Topic 
      id: String!
      name: String!
    

    type Query 
      topics: [Topic]
    
  `,
);

const client = new ApolloClient(
  cache,
  links: ApolloLink.from([
    // Other links ... ,
    store,
    // Other links ... ,
  ]),
);

检查我的缓存显示ROOT_QUERY


  topics:  ... ,
  viewer: User
    starredRepositories("first":100): StarredRepositoryConnection
      ...

以及所有实体normalized by apollo-cache-inmemory

【问题讨论】:

【参考方案1】:

据我了解,规范化数据完全超出了 Apollo 查询或缓存的范围。从缓存中获取对象后,您将需要创建某种辅助函数来根据需要展平对象。与 Redux 不同,没有中间件可以在其中处理操作并将其存储在缓存中。至少据我所知。我确实找到了graphql_normalizr,它可能会给你你想要的东西。对我来说,我会坚持简单地将 Query 包装在一个带有辅助函数的组件中,以便在返回之前通过 normalizr https://github.com/paularmstrong/normalizr/issues/108 的规范化模式运行获取的对象。

【讨论】:

但是,请谨慎操作。在 apollo-client 中,数据与 ui 直接绑定,因此当您违反合同时,更改 ui 的数据结构可能会反过来影响您。 感谢您的回答!我部分同意您关于规范化超出缓存范围的说法;但是标准化是由apollo-cache-inmemory 完成的。问题在于存储的形状和访问这些标准化数据;我找不到任何文档。你提出与 Redux 的比较并提到与 UI 的直接绑定给了我一个想法:我是否试图像使用 Redux 构建一样对所有内容进行建模?为了获得 Apollo,我需要从 Redux 中“忘记”什么吗? 当然没有中间件挂钩。我认为处理规范化的最佳方法是将您的 Query 包装在一个组件中,在该组件中,输出可以以 UI 可以使用的方式进行规范化。但是,就我上面的观点而言,也许您应该权衡规范化数据与迭代非规范化数据的成本。

以上是关于如何在 apollo-link-state 中标准化状态?的主要内容,如果未能解决你的问题,请参考以下文章

导入错误:无法从“apollo-link-state/lib/bundle.umd.js”中找到模块“graphql”

何时使用 apollo-link-state 以及何时使用 apollo-cache-inmemory

使用以未定义缓存状态结尾的 apollo-cache-persist 和 apollo-link-state

Apollo 客户端和更新表单

apollo-cache-inmemory 的驱逐规则是啥?

Apollo 中具有本地状态的变量返回数据