Я думаю, что самый простой способ достичь желаемого эффекта - фактически отказаться от оптимистичных обновлений в пользу самостоятельного управления состоянием компонента. На данный момент у меня нет пропускной способности, чтобы написать полный пример, но ваша базовая структура компонентов будет выглядеть следующим образом:
<ApolloConsumer>
{(client) => (
<Mutation mutation={CREATE_MUTATION}>
{(create) => (
<Mutation mutation={EDIT_MUTATION}>
{(edit) => (
<Form />
)}
</Mutation>
)}
</Mutation>
)}
</ApolloConsumer>
Давайте предположим, что мы имеем дело только с одним полем - name
. Ваш Form
компонент будет начинаться с начального состояния
{ name: '', created: null, updates: null }
После отправки форма будет выглядеть примерно так:
onCreate () {
this.props.create({ variables: { name: this.state.name } })
.then(({ data, errors }) => {
// handle errors whichever way
this.setState({ created: data.created })
if (this.state.updates) {
const id = data.created.id
this.props.update({ variables: { ...this.state.updates, id } })
}
})
.catch(errorHandler)
}
Тогда логика редактирования выглядит примерно так:
onEdit () {
if (this.state.created) {
const id = this.state.created.id
this.props.update({ variables: { name: this.state.name, id } })
.then(({ data, errors }) => {
this.setState({ updates: null })
})
.catch(errorHandler)
} else {
this.setState({ updates: { name: this.state.name } })
}
}
В сущности, ваша мутация редактирования либо запускается сразу же, когда пользователь отправляет (так как мы уже получили ответ от нашей мутации create) ... или изменения, сделанные пользователем, сохраняются и затем отправляются после завершения мутации create.
Это очень грубый пример, но он должен дать вам представление о том, как справиться с подобным сценарием. Самым большим недостатком является то, что существует вероятность того, что состояние вашего компонента не синхронизируется с кешем - вам нужно убедиться, что вы правильно обрабатываете ошибки, чтобы предотвратить это.
Это также означает, что если вы хотите использовать эту форму для только редактирования, вам нужно будет извлечь данные из кэша, а затем использовать его для заполнения вашего начального состояния (то есть this.state.created
в пример выше). Для этого вы можете использовать компонент Query
, просто убедитесь, что вы не визуализируете фактический компонент Form
, пока не получите опору data
, предоставленную компонентом Query
.