Как обновить реквизит отдельных компонентов после выполнения мутации с помощью Apollo

С избыточностью, когда состояние изменяется, он обновляет любые реквизиты компонентов, которые connected, в хранилище с mapStateToProps. Однако с Apollo при выполнении мутации любой компонент, использующий те же данные, получает новые реквизиты.

Я понимаю, что это ожидаемое поведение, потому что 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, тогда как компонент Edit обновляет username. Я хочу перерендерить Header при изменении username. Я не уверен, как это сделать без опроса запроса.


person Marc Greenstock    schedule 06.10.2016    source источник


Ответы (1)


Apollo хранит внутренний кеш запросов и может нормализовать наборы результатов с помощью dataIdFromObject используя внутренний кеш, хранящийся в хранилище избыточности.

Чтобы использовать внутренний кеш, вы должны установить dataIdFromObject при инициализации вашего клиента:

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

Затем при выполнении мутации убедитесь, что id возвращается в возвращаемом типе:

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

Запрос также должен содержать идентификатор:

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

Apollo распознает, что id идентичен между запросом и возвращаемым типом мутации, и соответствующим образом обновит данные запроса.

Я использую глобальные идентификаторы в своем GraphQL API, поэтому id всегда уникален для разных типов, но если вы используете идентификаторы с автоинкрементом или они не уникальны, вы можете использовать __typename из объекта:

const client = new ApolloClient({
  dataIdFromObject: o => `${o.__typename}:${o.id},`
})
person Marc Greenstock    schedule 07.10.2016