简体   繁体   English

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

[英]How to update a separate components props after performing a mutation with Apollo

With redux, when the state changes it updates any components props that is connect ed to the store with mapStateToProps . 使用redux,当状态更改时,它将使用mapStateToProps更新connect到商店的所有组件mapStateToProps However with Apollo when performing a mutation, any component that is using the same data receive the new props. 但是,使用Apollo进行突变时,任何使用相同数据的组件都会收到新的道具。

I understand this is expected behaviour because Apollo doesn't know that the data sets are the same. 我了解这是预期的行为,因为Apollo不知道数据集是相同的。 Here's an example of what I'm getting at: 这是我要了解的示例:

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})
  }
}

The Header component renders out the username , where as the Edit component updates the username . Header组件将呈现username ,而Edit组件将在其中更新username I want to re-render Header when username changes. 我想在username更改时重新呈现Header I'm not sure how to do this without polling the query. 我不确定如何在不轮询查询的情况下执行此操作。

Apollo keeps an internal cache of queries and is able to normalize the result sets with dataIdFromObject using the internal cache kept in the redux store. Apollo保留查询的内部缓存,并能够使用redux存储中保留的内部缓存通过dataIdFromObject标准化结果集。

In order to use the internal cache you must set dataIdFromObject when initializing your client: 为了使用内部缓存,必须在初始化客户端时设置dataIdFromObject

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

Then when performing a mutation, ensure the id is returned in the return type: 然后,在执行突变时,请确保id以返回类型返回:

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

The query should also contain the id: 查询还应包含ID:

const query = gql`query { me { id username } }`

Apollo will recognise that the id is identical between the query and the return type of the mutation and update the query data accordingly. Apollo将识别出查询和突变的返回类型之间的id是相同的,并相应地更新查询数据。

I'm using Global ID's in my GraphQL API so the id is always unique across types but if you are using auto-increment ids or they are not unique then you can use __typename from the object: 我在GraphQL API中使用了全局ID,因此该id在所有类型中始终是唯一的,但是如果您使用自动增量ID,或者它们不是唯一的,则可以从对象中使用__typename

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM