应用突变后 <Query> 中的空数据对象 returns
Empty data object returns in <Query> after mutation is applied for the same
"apollo-boost": "^0.1.13",
"apollo-link-context": "^1.0.8",
"graphql": "^0.13.2",
"graphql-tag": "^2.9.2",
"react-apollo": "^2.1.11",
当前代码结构
<div>
<Query
query={FETCH_CATEGORIES_AUTOCOMPLETE}
variables={{ ...filters }}
fetchPolicy="no-cache"
>
{({ loading, error, data }) => {
console.log('category', loading, error, data); // _______Label_( * )_______
if (error) return 'Error fetching products';
const { categories } = data;
return (
<React.Fragment>
{categories && (
<ReactSelectAsync
{...this.props.attributes}
options={categories.data}
handleFilterChange={this.props.handleCategoryFilterChange}
loading={loading}
labelKey="appendName"
/>
)}
</React.Fragment>
);
}}
</Query>
<Mutation mutation={CREATE_CATEGORY}>
{createCategory => (
<div>
// category create form
</div>
)}
</Mutation>
</div>
行为
最初,查询获取数据,我得到数据中的类别列表 given in Label_( * )
。
输入表单详细信息后,提交成功。
Issue:
然后,突然,在Label_( * )
中,数据对象是空的。
我该如何解决这个问题?
编辑
这些是回复:
类别 GET
{
"data": {
"categories": {
"page": 1,
"rows": 2,
"rowCount": 20,
"pages": 10,
"data": [
{
"id": "1",
"appendName": "Category A",
"__typename": "CategoryGETtype"
},
{
"id": "2",
"appendName": "Category B",
"__typename": "CategoryGETtype"
}
],
"__typename": "CategoryPageType"
}
}
}
类别创建
{
"data": {
"createCategory": {
"msg": "success",
"status": 200,
"category": {
"id": "21",
"name": "Category New",
"parent": null,
"__typename": "CategoryGETtype"
},
"__typename": "createCategory"
}
}
}
将fetchPolicy
更改为cache-and-network
后。它解决了这个问题。 Link to fetchPolicy Documentation
这样做,我还必须执行重新获取查询。
(我在遇到类似问题时遇到了这个问题,现在我已经解决了)
在 Apollo 中,当 returns 数据在不同的查询中使用时,该查询的结果将被更新。例如此查询 return 所有待办事项
query {
todos {
id
description
status
}
}
然后,如果我们将待办事项标记为已完成并带有变更
mutation CompleteTodo {
markCompleted(id: 3) {
todo {
id
status
}
}
}
结果是
{
todo: {
id: 3,
status: "completed"
__typename: "Todo"
}
}
然后 ID 为 1 的待办事项将更新其状态。当突变告诉查询它已经过时,但没有提供足够的信息来更新查询时,问题就来了。例如
query {
todos {
id
description
status
owner {
id
name
}
}
}
和
mutation CompleteTodo {
assignToUser(todoId: 3, userId: 12) {
todo {
id
owner {
id
}
}
}
}
示例结果:
{
todo: {
id: 3,
owner: {
id: 12,
__typename: "User"
},
__typename: "Todo"
}
}
想象一下,您的应用以前对 User:12 一无所知。事情是这样的
- Todo:3 的缓存知道它现在拥有所有者 User:12
- User:12 的缓存仅包含
{id:12}
,因为突变没有 return 名称字段
- 如果不重新获取(默认情况下不会发生),查询就无法为所有者的名称字段提供准确的信息。它更新为 return
data: {}
可能的解决方案
- 更改突变的 return 查询以包括查询需要的所有字段。
- 在更改后触发查询的重新获取(通过 refetchQueries),或包含缓存所需的所有内容的不同查询
- 手动更新缓存
其中,第一个可能是最简单和最快的。在 apollo 文档中对此进行了一些讨论,但我没有看到任何描述数据变空的特定行为的内容。
https://www.apollographql.com/docs/angular/features/cache-updates.html
感谢@clément-prévost 提供线索的评论:
Queries and mutations that fetch the same entity must query the same
fields. This is a way to avoid local cache issues.
"apollo-boost": "^0.1.13",
"apollo-link-context": "^1.0.8",
"graphql": "^0.13.2",
"graphql-tag": "^2.9.2",
"react-apollo": "^2.1.11",
当前代码结构
<div>
<Query
query={FETCH_CATEGORIES_AUTOCOMPLETE}
variables={{ ...filters }}
fetchPolicy="no-cache"
>
{({ loading, error, data }) => {
console.log('category', loading, error, data); // _______Label_( * )_______
if (error) return 'Error fetching products';
const { categories } = data;
return (
<React.Fragment>
{categories && (
<ReactSelectAsync
{...this.props.attributes}
options={categories.data}
handleFilterChange={this.props.handleCategoryFilterChange}
loading={loading}
labelKey="appendName"
/>
)}
</React.Fragment>
);
}}
</Query>
<Mutation mutation={CREATE_CATEGORY}>
{createCategory => (
<div>
// category create form
</div>
)}
</Mutation>
</div>
行为
最初,查询获取数据,我得到数据中的类别列表 given in Label_( * )
。
输入表单详细信息后,提交成功。
Issue:
然后,突然,在Label_( * )
中,数据对象是空的。
我该如何解决这个问题?
编辑
这些是回复:
类别 GET
{
"data": {
"categories": {
"page": 1,
"rows": 2,
"rowCount": 20,
"pages": 10,
"data": [
{
"id": "1",
"appendName": "Category A",
"__typename": "CategoryGETtype"
},
{
"id": "2",
"appendName": "Category B",
"__typename": "CategoryGETtype"
}
],
"__typename": "CategoryPageType"
}
}
}
类别创建
{
"data": {
"createCategory": {
"msg": "success",
"status": 200,
"category": {
"id": "21",
"name": "Category New",
"parent": null,
"__typename": "CategoryGETtype"
},
"__typename": "createCategory"
}
}
}
将fetchPolicy
更改为cache-and-network
后。它解决了这个问题。 Link to fetchPolicy Documentation
这样做,我还必须执行重新获取查询。
(我在遇到类似问题时遇到了这个问题,现在我已经解决了)
在 Apollo 中,当 returns 数据在不同的查询中使用时,该查询的结果将被更新。例如此查询 return 所有待办事项
query {
todos {
id
description
status
}
}
然后,如果我们将待办事项标记为已完成并带有变更
mutation CompleteTodo {
markCompleted(id: 3) {
todo {
id
status
}
}
}
结果是
{
todo: {
id: 3,
status: "completed"
__typename: "Todo"
}
}
然后 ID 为 1 的待办事项将更新其状态。当突变告诉查询它已经过时,但没有提供足够的信息来更新查询时,问题就来了。例如
query {
todos {
id
description
status
owner {
id
name
}
}
}
和
mutation CompleteTodo {
assignToUser(todoId: 3, userId: 12) {
todo {
id
owner {
id
}
}
}
}
示例结果:
{
todo: {
id: 3,
owner: {
id: 12,
__typename: "User"
},
__typename: "Todo"
}
}
想象一下,您的应用以前对 User:12 一无所知。事情是这样的
- Todo:3 的缓存知道它现在拥有所有者 User:12
- User:12 的缓存仅包含
{id:12}
,因为突变没有 return 名称字段 - 如果不重新获取(默认情况下不会发生),查询就无法为所有者的名称字段提供准确的信息。它更新为 return
data: {}
可能的解决方案
- 更改突变的 return 查询以包括查询需要的所有字段。
- 在更改后触发查询的重新获取(通过 refetchQueries),或包含缓存所需的所有内容的不同查询
- 手动更新缓存
其中,第一个可能是最简单和最快的。在 apollo 文档中对此进行了一些讨论,但我没有看到任何描述数据变空的特定行为的内容。
https://www.apollographql.com/docs/angular/features/cache-updates.html
感谢@clément-prévost 提供线索的评论:
Queries and mutations that fetch the same entity must query the same fields. This is a way to avoid local cache issues.