React-apollo 更新与重新获取
React-apollo update vs refetch
我正在使用 react-apollo 已经有一段时间了。对我来说已经成为问题的一件事是 refetch doesn't work when using a mutation 只要我一直在使用该应用程序,这就是一个已知问题。
我通过使用查询中可用的 refetch
道具解决了这个问题。
<Query query={query} fetchPolicy={fetchPolicy} {...props}>
{({ loading, data, error, refetch }) => {
... pass down to mutation
</Query>
但是我现在正在阅读您收到的 documentation
作为突变的一部分的更新方法,您应该在突变后使用它来更新您的应用程序。
能否使用update
函数来更新UI的数据,并在完成突变后更新?如果可以,这是现在进行更新的标准方式吗?
*使用 refetchQueries 无效
正如您在图像中看到的那样,console.info()
显示 data.status = "CREATED";
但直接从突变返回的请求是 data.status = "PICKED";
PICKED
是正确的并且更新数据库中的信息。
按照优先顺序,您的选项是:
什么都不做。对于单个节点的定期更新,只要变异 returns 是变异的结果,Apollo 就会自动为你更新缓存。当这无法按预期工作时,通常是因为查询缺少 id
(或 _id
)字段。当 id
字段不可用时,应向 InMemoryCache 构造函数提供自定义 dataIdFromObject 函数。当人们将 addTypename
选项设置为 false
时,自动缓存更新也会失败。
使用update
. update
函数会在你的变异完成后运行,让你操作直接缓存。如果突变影响字段 returning 节点列表,则这是必要的。与简单更新不同,Apollo 无法推断列表是否应该在突变后更新(以及如何更新),因此我们必须自己直接更新缓存。这通常在创建和删除突变之后是必需的,但如果更新的节点应该添加或删除到 return 列表的某个字段,则在更新突变之后也可能需要。 docs 详细介绍了如何执行此操作。
<Mutation
mutation={ADD_TODO}
update={(cache, { data: { addTodo } }) => {
const { todos } = cache.readQuery({ query: GET_TODOS });
cache.writeQuery({
query: GET_TODOS,
data: { todos: todos.concat([addTodo]) },
});
}}
>
{(addTodo) =>(...)}
</Mutation>
- 使用
refetchQueries
. 除了更新缓存,你还可以提供一个refetchQueries
函数,它应该return一个数组表示要重新获取的查询的对象。这通常不如使用 update
可取,因为它需要对服务器进行一次或多次额外调用。但是,如果突变没有 return 足够的信息来手动正确更新缓存,则可能有必要。注意:returned 数组也可能是一个 array of strings 表示操作名称,尽管这没有很好的记录。
<Mutation
mutation={ADD_TODO}
refetchQueries={() => [
{ query: TODOS_QUERY, variables: { foo: 'BAR' } },
]}
>
{(addTodo) =>(...)}
</Mutation>
使用refetch
。正如您在问题中已经展示的那样,可以使用 Mutation
组件内的 Query
组件提供的 refetch
函数来重新获取该特定查询。如果您的 Mutation
组件已经嵌套在 Query
组件中,这很好,但通常使用 refetchQueries
将是一个更清晰的解决方案,特别是在需要重新获取多个查询时。
使用updateQueries
。这是一个遗留选项,不再是 well-documented,但在添加 update
之前提供了与 update
类似的功能。不应使用它,因为它可能在将来被弃用。
更新:
您还可以设置架构,使查询可以作为变更的一部分重新获取。有关详细信息,请参阅 this article。
我正在使用 react-apollo 已经有一段时间了。对我来说已经成为问题的一件事是 refetch doesn't work when using a mutation 只要我一直在使用该应用程序,这就是一个已知问题。
我通过使用查询中可用的 refetch
道具解决了这个问题。
<Query query={query} fetchPolicy={fetchPolicy} {...props}>
{({ loading, data, error, refetch }) => {
... pass down to mutation
</Query>
但是我现在正在阅读您收到的 documentation 作为突变的一部分的更新方法,您应该在突变后使用它来更新您的应用程序。
能否使用update
函数来更新UI的数据,并在完成突变后更新?如果可以,这是现在进行更新的标准方式吗?
*使用 refetchQueries 无效
正如您在图像中看到的那样,console.info()
显示 data.status = "CREATED";
但直接从突变返回的请求是 data.status = "PICKED";
PICKED
是正确的并且更新数据库中的信息。
按照优先顺序,您的选项是:
什么都不做。对于单个节点的定期更新,只要变异 returns 是变异的结果,Apollo 就会自动为你更新缓存。当这无法按预期工作时,通常是因为查询缺少
id
(或_id
)字段。当id
字段不可用时,应向 InMemoryCache 构造函数提供自定义 dataIdFromObject 函数。当人们将addTypename
选项设置为false
时,自动缓存更新也会失败。使用
update
.update
函数会在你的变异完成后运行,让你操作直接缓存。如果突变影响字段 returning 节点列表,则这是必要的。与简单更新不同,Apollo 无法推断列表是否应该在突变后更新(以及如何更新),因此我们必须自己直接更新缓存。这通常在创建和删除突变之后是必需的,但如果更新的节点应该添加或删除到 return 列表的某个字段,则在更新突变之后也可能需要。 docs 详细介绍了如何执行此操作。
<Mutation
mutation={ADD_TODO}
update={(cache, { data: { addTodo } }) => {
const { todos } = cache.readQuery({ query: GET_TODOS });
cache.writeQuery({
query: GET_TODOS,
data: { todos: todos.concat([addTodo]) },
});
}}
>
{(addTodo) =>(...)}
</Mutation>
- 使用
refetchQueries
. 除了更新缓存,你还可以提供一个refetchQueries
函数,它应该return一个数组表示要重新获取的查询的对象。这通常不如使用update
可取,因为它需要对服务器进行一次或多次额外调用。但是,如果突变没有 return 足够的信息来手动正确更新缓存,则可能有必要。注意:returned 数组也可能是一个 array of strings 表示操作名称,尽管这没有很好的记录。
<Mutation
mutation={ADD_TODO}
refetchQueries={() => [
{ query: TODOS_QUERY, variables: { foo: 'BAR' } },
]}
>
{(addTodo) =>(...)}
</Mutation>
使用
refetch
。正如您在问题中已经展示的那样,可以使用Mutation
组件内的Query
组件提供的refetch
函数来重新获取该特定查询。如果您的Mutation
组件已经嵌套在Query
组件中,这很好,但通常使用refetchQueries
将是一个更清晰的解决方案,特别是在需要重新获取多个查询时。使用
updateQueries
。这是一个遗留选项,不再是 well-documented,但在添加update
之前提供了与update
类似的功能。不应使用它,因为它可能在将来被弃用。
更新:
您还可以设置架构,使查询可以作为变更的一部分重新获取。有关详细信息,请参阅 this article。