问题描述
我有一个突变(上载Transaction),返回某些名为Transaction的对象的某些列表.
#import "TransactionFields.gql" mutation UploadTransaction($files: [Upload!]!) { uploadFile(files: $files){ transactions { ...TransactionFields } } }
从后端返回的事务(石墨烯)具有ID和TypeName字段.因此,它应该自动更新缓存中的交易.在Apollo的Chrome Dev工具中,我可以看到新的交易:
我也有一个查询gettransactions获取所有事务对象.
#import "TransactionFields.gql" query GetTransactions { transactions { ...TransactionFields } }
但是,我看不到查询返回新添加的交易.在初始加载期间,Apollo客户端加载了292件交易,并在root_query下显示.它不断返回相同的292笔交易. uploadTransaction突变添加开发工具中的"交易"类型"事务"的新对象,而不会影响Dev-tools中的root_query或我在代码中的我的查询.
transactionfields.gql是
fragment TransactionFields on Transaction { id timestamp description amount category { id name } currency }
知道我在做什么错?我是Apollo客户端的新手和GraphQl
推荐答案
来自
因此,为了更新缓存,您有两个选项: 使用文档中使用update的示例: 阅读文档以获取其他详细信息.
update (cache, { data: { addTodo } }) {
const { todos } = cache.readQuery({ query: GET_TODOS });
cache.writeQuery({
query: GET_TODOS,
data: { todos: todos.concat([addTodo]) },
});
}
问题描述
I have a mutation (UploadTransaction) returning certain list of certain object named Transaction.
#import "TransactionFields.gql" mutation UploadTransaction($files: [Upload!]!) { uploadFile(files: $files){ transactions { ...TransactionFields } } }
Transaction returned from backend (graphene) has id and typename field. Hence it should automatically update Transaction in the cache. In chrome dev tools for Apollo, I can see new transactions:
I also have a query GetTransactions fetching all Transaction objects.
#import "TransactionFields.gql" query GetTransactions { transactions { ...TransactionFields } }
However I don't see newly added Transaction being returned by the query. During initial load, Apollo client loaded 292 transactions which it shows under ROOT_QUERY. It keeps returning same 292 transactions. UploadTransaction mutation add new object of type "Transaction" in cache in dev-tools without affecting ROOT_QUERY in dev-tools or my query in code.
TransactionFields.gql is
fragment TransactionFields on Transaction { id timestamp description amount category { id name } currency }
Any idea what am I doing wrong? I am new to apollo client and graphql
推荐答案
From the docs:
If a mutation updates a single existing entity, Apollo Client can automatically update that entity's value in its cache when the mutation returns. To do so, the mutation must return the id of the modified entity, along with the values of the fields that were modified. Conveniently, mutations do this by default in Apollo Client...
If a mutation modifies multiple entities, or if it creates or deletes entities, the Apollo Client cache is not automatically updated to reflect the result of the mutation. To resolve this, your call to useMutation can include an update function.
If you have a query that returns a list of entities (for example, users) and then create or delete a user, Apollo has no way of knowing that the list should be updated to reflect your mutation. The reason for this is two fold
- There's no way for Apollo to know what a mutation is actually doing. All it knows is what fields you are requesting and what arguments you are passing those fields. We might assume that a mutation that includes words like "insert" or "create" is inserting something on the backend but that's not a given.
- There's no way to know that inserting, deleting or updating a user should update a particular query. Your query might be for all users with the name "Bob" -- if you create a user with the name "Susan", the query shouldn't be updated to reflect that addition. Similarly, if a mutation updates a user, the query might need to be updated to reflect the change. Whether it should or not ultimately boils down to business rules that only your server knows about.
So, in order to update the cache, you have two options:
- Trigger a refetch of the relevant queries. You can do this by either passing a refetchQueries option to your useMutation hook, or by manually calling refetch on those queries. Since this requires one or more additional requests to your server, it's the slower and more expensive option but can be the right option when A) you don't want to inject a bunch of business logic into your client or B) the updates to the cache are complicated and extensive.
- Provide an update function to your useMutation hook that tells Apollo how to update the cache based on the results of the mutation. This saves you from making any additional requests, but does mean you have to duplicate some business logic between your server and your client.
The example of using update from the docs:
update (cache, { data: { addTodo } }) { const { todos } = cache.readQuery({ query: GET_TODOS }); cache.writeQuery({ query: GET_TODOS, data: { todos: todos.concat([addTodo]) }, }); }
Read the docs for additional details.