缺少对象选择集 GraphQL+Apollo 错误
Missing selection set for object GraphQL+Apollo error
我有一组突变可以触发某些类型的弹出窗口的本地状态。它们通常是这样设置的:
openDialog: (_, variables, { cache }) => {
const data = {
popups: {
...popups,
dialog: {
id: 'dialog',
__typename: 'Dialog',
type: variables.type
}
}
};
cache.writeData({
data: data
});
return null;
}
我传入的默认值如下所示:
const defaults = {
popups: {
__typename: TYPENAMES.POPUPS,
id,
message: null,
modal: null,
menu: null,
dialog: null
}
};
它们在我的 React 代码中的使用方式是使用 Mutation 包装器组件,如下所示:
const OPEN_ALERT_FORM = gql`
mutation AlertOpenDialog($type: String!) {
openDialog(type: $type) @client
}
`;
class Alert extends Component {
render() {
return (
<Mutation mutation={OPEN_ALERT_FORM} variables={{ type: ALERT_FORM }}>
{openDialog => {
return (
<Button
classes="alert-button"
onClick={openDialog}
label="Trigger Alert"
/>
);
}}
</Mutation>
);
}
}
对于我的各种弹出窗口(我有 3 或 4 个不同的弹出窗口,例如 menu
和 modal
),打开和关闭它们的突变看起来都一样,只是类型名称和内容不同等. 但是,对于对话框,当我点击它们时出现这个错误:
网络错误:缺少为查询字段对话框返回的对话框类型对象的选择集
...然后触发组件从页面中消失。另外,一旦发生这种情况,当您尝试单击它们时,所有其他弹出类型都会消失,然后重新抛出该错误,或者说:
未捕获错误:引发了跨源错误。 React 无法访问开发中的实际错误对象。
我已经尝试重写对话框以匹配其他弹出类型,并重写组件,但我仍然遇到此错误。它似乎是特定于对话+Apollo 的。
这个问题的根源是什么?它不可能是后端的东西,因为这只是处理本地的 Apollo。我以前没见过这个错误,我不确定从这里去哪里。
通过将 dialog
字段视为字符串而不是对象来解决这个问题。将函数更改为这个可以解决问题并使错误消失:
openDialog: (_, variables, { cache }) => {
const data = {
popups: {
...popups,
dialog: variables.type
}
};
cache.writeData({
data: data
});
return null;
}
解决方案是向查询添加字段(相对于声明要获取的顶级对象而不指定要获取的字段)。如果你有类似的东西:
{
popups @client {
id
dialog
}
}
您必须在 dialog
中声明一些要获取的字段,例如 id
:
{
popups @client {
id
dialog {
id
}
}
}
实际问题的答案似乎在查询中。最初 Apollo 客户端没有验证 @client
queries/mutations 的类型,所以你的突变看起来就像你在问题中写的:
mutation AlertOpenDialog($type: String!) {
openDialog(type: $type) @client
}
上面的正确写法是指定 (select) 您想要在响应中获得的所有简单类型(标量)字段。所以关于@Vic 的回答,突变应该看起来更像:
mutation AlertOpenDialog($type: String!) {
openDialog(type: $type) @client {
dialog {
id
}
}
}
我有一组突变可以触发某些类型的弹出窗口的本地状态。它们通常是这样设置的:
openDialog: (_, variables, { cache }) => {
const data = {
popups: {
...popups,
dialog: {
id: 'dialog',
__typename: 'Dialog',
type: variables.type
}
}
};
cache.writeData({
data: data
});
return null;
}
我传入的默认值如下所示:
const defaults = {
popups: {
__typename: TYPENAMES.POPUPS,
id,
message: null,
modal: null,
menu: null,
dialog: null
}
};
它们在我的 React 代码中的使用方式是使用 Mutation 包装器组件,如下所示:
const OPEN_ALERT_FORM = gql`
mutation AlertOpenDialog($type: String!) {
openDialog(type: $type) @client
}
`;
class Alert extends Component {
render() {
return (
<Mutation mutation={OPEN_ALERT_FORM} variables={{ type: ALERT_FORM }}>
{openDialog => {
return (
<Button
classes="alert-button"
onClick={openDialog}
label="Trigger Alert"
/>
);
}}
</Mutation>
);
}
}
对于我的各种弹出窗口(我有 3 或 4 个不同的弹出窗口,例如 menu
和 modal
),打开和关闭它们的突变看起来都一样,只是类型名称和内容不同等. 但是,对于对话框,当我点击它们时出现这个错误:
网络错误:缺少为查询字段对话框返回的对话框类型对象的选择集
...然后触发组件从页面中消失。另外,一旦发生这种情况,当您尝试单击它们时,所有其他弹出类型都会消失,然后重新抛出该错误,或者说:
未捕获错误:引发了跨源错误。 React 无法访问开发中的实际错误对象。
我已经尝试重写对话框以匹配其他弹出类型,并重写组件,但我仍然遇到此错误。它似乎是特定于对话+Apollo 的。 这个问题的根源是什么?它不可能是后端的东西,因为这只是处理本地的 Apollo。我以前没见过这个错误,我不确定从这里去哪里。
通过将 dialog
字段视为字符串而不是对象来解决这个问题。将函数更改为这个可以解决问题并使错误消失:
openDialog: (_, variables, { cache }) => {
const data = {
popups: {
...popups,
dialog: variables.type
}
};
cache.writeData({
data: data
});
return null;
}
解决方案是向查询添加字段(相对于声明要获取的顶级对象而不指定要获取的字段)。如果你有类似的东西:
{
popups @client {
id
dialog
}
}
您必须在 dialog
中声明一些要获取的字段,例如 id
:
{
popups @client {
id
dialog {
id
}
}
}
实际问题的答案似乎在查询中。最初 Apollo 客户端没有验证 @client
queries/mutations 的类型,所以你的突变看起来就像你在问题中写的:
mutation AlertOpenDialog($type: String!) {
openDialog(type: $type) @client
}
上面的正确写法是指定 (select) 您想要在响应中获得的所有简单类型(标量)字段。所以关于@Vic 的回答,突变应该看起来更像:
mutation AlertOpenDialog($type: String!) {
openDialog(type: $type) @client {
dialog {
id
}
}
}