使用 Apollo 执行突变后如何更新单独的组件道具

Posted

技术标签:

【中文标题】使用 Apollo 执行突变后如何更新单独的组件道具【英文标题】:How to update a separate components props after performing a mutation with Apollo 【发布时间】:2017-02-15 11:19:45 【问题描述】:

使用 redux,当状态发生变化时,它会将 connected 的任何组件 props 更新到带有 mapStateToProps 的商店。但是使用 Apollo 在执行突变时,任何使用相同数据的组件都会收到新的 props。

我理解这是预期的行为,因为 Apollo 不知道数据集是相同的。这是我要了解的示例:

const query = gql`query  me  username  `

@graphql(query)
class Header extends React.Component 
  render () 
    return <h1>this.props.data.me.username</h1>
  


const mutation = gql`mutation updateAccount($username: String!) 
  updateAccount(username: $username) 
    me 
      username
    
  
`
@graphql(mutation)
class Edit extends React.Component 
  render () 
    # ...
  
  onSubmit(e) 
    e.preventDefault()
    this.props.mutate(variables: username: this.state.username)
  

Header 组件渲染出username,而编辑组件更新username。当username 更改时,我想重新渲染Header。如果不轮询查询,我不确定如何执行此操作。

【问题讨论】:

【参考方案1】:

Apollo 保留一个内部查询缓存,并且能够使用 redux 存储中保存的内部缓存对带有 dataIdFromObject 的结果集进行规范化。

为了使用内部缓存,您必须在初始化客户端时设置dataIdFromObject

const client = new ApolloClient(
  dataIdFromObject: o => o.id
)

然后在执行突变时,确保在返回类型中返回id

const mutation = gql`mutation updateAccount($username: String!) 
  updateAccount(username: $username) 
    me 
      id
      username
    
  
`

查询还应包含 id:

const query = gql`query  me  id username  `

Apollo 将识别出查询和突变的返回类型之间的id 相同,并相应地更新查询数据。

我在我的 GraphQL API 中使用全局 ID,因此 id 在类型之间始终是唯一的,但如果您使用自动增量 ID 或者它们不是唯一的,那么您可以使用对象中的 __typename

const client = new ApolloClient(
  dataIdFromObject: o => `$o.__typename:$o.id,`
)

【讨论】:

以上是关于使用 Apollo 执行突变后如何更新单独的组件道具的主要内容,如果未能解决你的问题,请参考以下文章

使用 MockedProvider 进行测试时使用 Apollo 突变更新存储

突变后的 Apollo 更新不会触发重新渲染

使用突变响应更新 apollo 客户端

如何在 Apollo / GraphQL 发生突变后更新缓存?

如何在多个视图中处理突变后的缓存更新?

如何在使用表单组件时在 apollo-client 中链接突变