我认为实现所需效果的最简单方法是实际放弃乐观更新,转而自行管理组件状态。目前我没有足够的能力写出一个完整的例子,但是你的基本组件结构应该是这样的:
<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 } })
}
}
实际上,您的编辑突变要么在用户提交时立即触发(因为我们已经从我们的创建突变得到响应)......或者用户所做的更改被保留,然后在创建突变完成后发送。
这是一个非常粗略的示例,但应该让您对如何处理这种情况有所了解。最大的缺点是您的组件状态可能会与缓存不同步——您需要确保正确处理错误以防止这种情况发生。
这也意味着如果您想使用此表单进行只是编辑,您需要从缓存中获取数据,然后使用它来填充您的初始状态(即this.state.created在上面的例子中)。您可以为此使用 Query 组件,只要确保在获得 Query 组件提供的 data 属性之前不渲染实际的 Form 组件。