问题描述
我正在使用react-apollo,已经使用了相当长的时间.对我来说已经成为问题的一件事是,
如您在图像中所见, console.info()
显示 data.status ="CREATED";
,但请求直接从突变返回是 data.status ="PICKED";
PICKED
是数据库中正确且最新的信息.
按照优先顺序,您可以选择以下选项:
-
不执行任何操作.对于定期更新单个节点,只要变异返回变异结果,Apollo就会为您自动更新缓存.当此操作无法按预期工作时,通常是因为查询缺少
id
(或_id
)字段.当id
字段不可用时,自定义 dataIdFromObject函数应提供给InMemoryCache构造函数.当人们将addTypename
选项设置为false
时,自动缓存更新也会失败. -
使用
update
.update
函数将在您的变异完成后运行,并让您直接操作缓存.如果该突变影响返回一个节点列表的字段,则这是必需的.与简单更新不同,Apollo无法推断出突变后是否应该更新列表(以及如何更新),因此我们必须自己直接更新缓存.在创建和删除突变之后,这通常是必需的,但是在更新突变之后,如果应将已更新的节点添加或删除到返回列表的某个字段中,则也可能需要这样做. docs 进行了大量详细的解释该怎么做.
<静音变异= {ADD_TODO}update = {(cache,{data:{addTodo}})=>{const {todos} = cache.readQuery({query:GET_TODOS});cache.writeQuery({查询:GET_TODOS,数据:{todos:todos.concat([addTodo])},});}}>{(addTodo)=>(...)}</静音>
- 使用
refetchQueries
.代替更新缓存,您还可以提供refetchQueries
函数,该函数应返回表示对象的数组.查询以重新提取.通常,与使用update
相比,这种方法不那么理想,因为它需要对服务器进行一个或多个其他调用.但是,如果突变没有返回足够的信息来手动正确更新缓存,则可能是必要的.注意:返回的数组也可以是字符串数组,表示操作名称,尽管没有充分记录.
<静音变异= {ADD_TODO}refetchQueries = {()=>[{查询:TODOS_QUERY,变量:{foo:'BAR'}},]}>{(addTodo)=>(...)}</静音>
-
使用
refetch
.正如您在问题中已经显示的那样,可以使用Mutation
组件内的Query
组件提供的refetch
函数来重新获取该特定查询.如果您的Mutation
组件已经嵌套在Query
组件中,则很好,但是通常使用refetchQueries
是一个更干净的解决方案,尤其是在多个查询的情况下需要重新获取. -
使用
updateQueries
.这是一个遗留选项,已不再有据可查,但在添加update
之前提供了与update
类似的功能.不应使用它,因为将来可能会不推荐使用它.
更新:
您还可以通过以下方式设置模式:查询可以作为突变的一部分重新获得.有关更多详细信息,请参见这篇文章./p>
I am using react-apollo and have been for quite some time. One thing that has already been a problem for me is the fact that refetch doesn't work when using a mutation This has been a know issue for as long as I have been using the app.
I have got round this by using the refetch
prop that is available on a query.
<Query query={query} fetchPolicy={fetchPolicy} {...props}>
{({ loading, data, error, refetch }) => {
... pass down to mutation
</Query>
However I am now reading in the documentation that you recievean update method as part of a mutation and you should use this to update your application after a mutation.
Can you use the update
function to update your UI's data and have it update after finishing a mutation? If you can, is this the standard way to do updates now?
*Using refetchQueries not working
As you can see in the image the console.info()
displays that the data.status = "CREATED";
but the request coming back from the mutation directly is data.status = "PICKED";
PICKED
is the correct and uptodate information in the DB.
In order of preference, your options are:
Do nothing. For regular updates to an individual node, as long as the mutation returns the mutated result, Apollo will update the cache automatically for you. When this fails to work as expected, it's usually because the query is missing the
id
(or_id
) field. When anid
field is not available, a custom dataIdFromObject function should be provided to the InMemoryCache constructor. Automatic cache updates also fail when people set theaddTypename
option tofalse
.Use
update
. Theupdate
function will run after your mutation completes, and lets you manipulate the cache directly. This is necessary if the mutation affects a field returning a list of nodes. Unlike simple updates, Apollo has no way to infer whether the list should be updated (and how) following the mutation, so we have to directly update the cache ourselves. This is typically necessary following create and delete mutations, but may also be needed after an update mutation if the updated node should be added or removed to some field that returns a list. The docs go into a good deal of detail explaining how to do this.
<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>
- Use
refetchQueries
. Instead of updating the cache, you may also provide arefetchQueries
function, which should return an array of objects representing the queries to refetch. This is generally less desirable than usingupdate
since it requires one or more additional calls to the server. However, it may be necessary if the mutation does not return enough information to correctly update the cache manually. NOTE: The returned array may also be an array of strings representing operation names, though this is not well documented.
<Mutation
mutation={ADD_TODO}
refetchQueries={() => [
{ query: TODOS_QUERY, variables: { foo: 'BAR' } },
]}
>
{(addTodo) =>(...)}
</Mutation>
Use
refetch
. As you already showed in your question, it's possible to use therefetch
function provided by aQuery
component inside yourMutation
component to refetch that specific query. This is fine if yourMutation
component is already nested inside theQuery
component, but generally usingrefetchQueries
will be a cleaner solution, particularly if multiple queries need to be refetched.Use
updateQueries
. This is a legacy option that's no longer well-documented, but provided similar functionality toupdate
beforeupdate
was added. It should not be used as it may be deprecated in the future.
UPDATE:
You may also set up your schema in such a way that queries can be refetched as part of your mutation. See this article for more details.
这篇关于React-Apollo更新与Refetch的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!