我认为实现所需效果的最简单方法是实际放弃乐观更新,转而自己管理组件状态。我现在没有足够的能力写出一个完整的例子,但是你的基本组件结构应该是这样的:
<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
组件,只需确保在组件提供的道具Form
之前不渲染实际组件。data
Query