readQuery 不适用于 Apollo 和 GraphQL 应用程序中的分页

Posted

技术标签:

【中文标题】readQuery 不适用于 Apollo 和 GraphQL 应用程序中的分页【英文标题】:readQuery not working with pagination in Apollo & GraphQL app 【发布时间】:2017-11-14 05:17:44 【问题描述】:

我的应用程序进行了以下设置。我有一个LinkList 组件,它呈现Link 组件的列表。然后我还有一个CreateLink 组件来创建新的链接。两者都使用react-router在不同的路由下渲染:

<Switch>
  <Route exact path='/create' component=CreateLink/>
  <Route exact path='/:page' component=LinkList/>
</Switch>

我的 GraphQL 架构中的 Link 类型如下所示:

type Link implements Node 
  url: String!
  postedBy: User! @relation(name: "UsersLinks")
  votes: [Vote!]! @relation(name: "VotesOnLink")
  comments: [Comment!]! @relation(name: "CommentsOnLink")

我正在使用 Apollo 客户端,并希望在 CreateLink 组件中创建新的 Link 后使用命令式存储 API 更新列表。

await this.props.createLinkMutation(
  variables: 
    description,
    url,
    postedById
  ,
  update: (store,  data:  createLink  ) => 
    const data = store.readQuery( query: ALL_LINKS_QUERY ) // ERROR
    console.log(`data: `, data)
  
)

问题是store.readQuery(...)抛出错误:

proxyConsole.js:56 Error: Can't find field allLinks() on object (ROOT_QUERY) 
  "allLinks(\"first\":2,\"skip\":10)": [
    
      "type": "id",
      "id": "Link:cj3ucdguyvzdq0131pzvn37as",
      "generated": false
    
  ],
  "_allLinksMeta": 
    "type": "id",
    "id": "$ROOT_QUERY._allLinksMeta",
    "generated": true
  
.

这是我在LinkList 组件中获取链接列表的方式:

export const ALL_LINKS_QUERY = gql`
  query AllLinksQuery($first: Int, $skip: Int) 
    allLinks(first: $first, skip: $skip) 
      id
      url
      description
      createdAt
      postedBy 
        id
        name
      
      votes 
        id
      
    
    _allLinksMeta 
      count
    
  
`

export default graphql(ALL_LINKS_QUERY, 
  name: 'allLinksQuery',
  options: (ownProps) => 
    const  pathname  = ownProps.location
    const page = parseInt(pathname.substring(1, pathname.length))
    return 
      variables: 
        skip: (page - 1) * LINKS_PER_PAGE,
        first: LINKS_PER_PAGE
      ,
      fetchPolicy: 'network-only'
    
  
) (LinkList)

我猜这个问题与我的分页方法有关,但我仍然不知道如何解决它。有人可以在这里指出我正确的方向吗?

【问题讨论】:

【参考方案1】:

如何从商店读取分页列表取决于您如何进行分页。如果您使用的是fetchMore,那么所有数据都将存储在查询的原始键下,在这种情况下,我猜是用 first: 2, skip: 0 获取的。这意味着为了从存储中读取更新后的列表,您必须使用相同的参数,使用 first: 2, skip: 0 作为变量。

PS:Apollo 这样做的原因是因为它仍然允许您通过突变或更新存储相对轻松地更新列表。如果每个页面都是单独存储的,那么在列表的中间或开头插入一个项目将非常复杂,因为所有页面都可能需要移动。

也就是说,我们可能会引入一个名为@connection(name: "ABC") 的新客户端指令,它可以让您明确指定要在哪个键下存储连接,而不是自动将其存储在原始变量下。如果您想在 Apollo Client 上打开一个问题,很高兴谈论它。

【讨论】:

那么...你是怎么解决这个问题的?

以上是关于readQuery 不适用于 Apollo 和 GraphQL 应用程序中的分页的主要内容,如果未能解决你的问题,请参考以下文章

当数据在缓存中时,Apollo Client client.readQuery 返回 null

变异后的Apollo缓存未更新

React-apollo 突变 writeQuery 不更新 ui

我的突变适用于 Amplify,但不适用于 Apollo。为啥?

Apollo + Angular 突变不适用于变量

Apollo 客户端订阅适用于 Playground,但不适用于 Expo 应用程序