使用 RelayRouter 导航 relay.js 应用程序抛出无效状态更改错误
Navigating relay.js app with RelayRouter throwing Invalid State Change error
我正在编写一个 relay.js 应用程序,我正在使用 react-relay-router 进行路由。路由有效,但我认为它暴露了我对如何跨不同视图组织查询片段的误解。
在app.js
中定义的路由
const rootComponent =
(<RelayRouter history={hashHistory}>
<Route path="/"
component={App}
queries={ViewerQueries}
onReadyStateChange={this.handleStateChange}
>
<IndexRoute
component={Dashboard}
queries={ViewerQueries}
/>
<Route
path="/org_setup"
component={OrgSetup}
queries={ViewerQueries}
/>
<Route
path="/admin/data_models"
component={DataModelList}
queries={ViewerQueries}
/>
</Route>
</RelayRouter>);
ReactDOM.render(rootComponent, mountNode);
在DataModelList.js
中查询片段声明
export default Relay.createContainer(DataModelList, {
fragments: {
viewer: () => Relay.QL`
fragment on User {
dataModels(first: 10) {
edges {
node {
id,
name,
isAuthority,
categories(first: 10) {
edges {
node {
id,
name,
tags(first: 10) {
edges {
node {
id,
code,
label,
}
}
}
}
}
},
adapter {
categories(first: 10) {
edges {
node {
id,
name,
}
}
}
}
}
}
},
}
`,
},
});
OrgSetup.js
中的查询片段
export default Relay.createContainer(OrgSetup, {
fragments: {
viewer: () => Relay.QL`
fragment on User {
dataModels(first: 10) {
edges {
node {
id,
name,
isAuthority,
categories(first: 10) {
edges {
node {
id,
name,
tags(first: 10) {
edges {
node {
id,
code,
label,
}
}
}
}
}
},
}
}
},
}
`,
},
});
在 DataModelList
和 OrgSetup
之间(任一方向)导航时,我在控制台中看到以下错误:
Server request for query `ViewerQueries` failed for the following reasons:
1. Cannot query field "node" on "Query".
rQueries($id_0:ID!){node(id:$id_0){id,__typename,...F0}} fra
Warning: RelayReadyState: Invalid state change from
{"aborted":false,"done":false,"error":{"source":{"data":null,"errors":
[{"message":"Cannot query field \"node\" on \"Query\".","locations":
[{"line":1,"column":32}]}]}},"ready":false,"stale":false}` to `{"error":
{"source":{"data":null,"errors":[{"message":"Cannot query field \"node\" on
\"Query\".","locations":[{"line":1,"column":32}]}]}}}`.warning @
app.js:31567update @ app.js:39409onRejected @ app.js:39035tryCallOne @
app.js:30045(anonymous function) @ app.js:30131flush @ app.js:30279
我可以通过使两个视图中的查询片段相同来防止此错误的发生——特别是通过添加 adapter
片段。
然而,这感觉不对。它们不需要完全相同(事实上,由于这对我来说是一个学习应用程序,它们现在有些故意臃肿),其他视图当然不会共享这些数据需求。
- 保持查询声明简洁的最佳做法是什么?
理想情况下,我会让顶级视图只声明顶级数据
要求。具体来说,在我的示例视图文件中,我会请求
只有
viewer
和他们的 dataModels
,然后允许 child
组件来表达他们的需求,请求任何嵌套数据(例如
categories
、tags
或 adapters
及其各自的 categories
).
invalid state change
错误的真正含义是什么?我可以看到
它对完全匹配的查询感到满意,但我不能
想象不相关的视图需要共享查询声明。我
怀疑这是我在别处做错事的副产品。
谢谢!
当查询发生变化时(例如,由于路由转换或对 setVariables()
的调用),中继将区分您来自的查询和您要去的查询,计算最小值查询让你从 A 到 B。在你的例子中,中继从客户端存储的一系列已知记录(已经获取的记录)开始,并尝试只获取这些确切记录上的新字段,以构建一个完整的世界图景。这些重新获取依赖于一种叫做 node interface.
的东西
中继兼容的 GraphQL 服务器必须公开一个名为 node
的根字段,它可以在给定全局 ID 的情况下获取任何记录。该字段必须采用类型为 GraphQLID!
的 id
参数。
有关如何构建此类根字段的示例,请参阅 this graphql-js
example。
我正在编写一个 relay.js 应用程序,我正在使用 react-relay-router 进行路由。路由有效,但我认为它暴露了我对如何跨不同视图组织查询片段的误解。
在app.js
中定义的路由const rootComponent =
(<RelayRouter history={hashHistory}>
<Route path="/"
component={App}
queries={ViewerQueries}
onReadyStateChange={this.handleStateChange}
>
<IndexRoute
component={Dashboard}
queries={ViewerQueries}
/>
<Route
path="/org_setup"
component={OrgSetup}
queries={ViewerQueries}
/>
<Route
path="/admin/data_models"
component={DataModelList}
queries={ViewerQueries}
/>
</Route>
</RelayRouter>);
ReactDOM.render(rootComponent, mountNode);
在DataModelList.js
中查询片段声明export default Relay.createContainer(DataModelList, {
fragments: {
viewer: () => Relay.QL`
fragment on User {
dataModels(first: 10) {
edges {
node {
id,
name,
isAuthority,
categories(first: 10) {
edges {
node {
id,
name,
tags(first: 10) {
edges {
node {
id,
code,
label,
}
}
}
}
}
},
adapter {
categories(first: 10) {
edges {
node {
id,
name,
}
}
}
}
}
}
},
}
`,
},
});
OrgSetup.js
中的查询片段export default Relay.createContainer(OrgSetup, {
fragments: {
viewer: () => Relay.QL`
fragment on User {
dataModels(first: 10) {
edges {
node {
id,
name,
isAuthority,
categories(first: 10) {
edges {
node {
id,
name,
tags(first: 10) {
edges {
node {
id,
code,
label,
}
}
}
}
}
},
}
}
},
}
`,
},
});
在 DataModelList
和 OrgSetup
之间(任一方向)导航时,我在控制台中看到以下错误:
Server request for query `ViewerQueries` failed for the following reasons:
1. Cannot query field "node" on "Query".
rQueries($id_0:ID!){node(id:$id_0){id,__typename,...F0}} fra
Warning: RelayReadyState: Invalid state change from
{"aborted":false,"done":false,"error":{"source":{"data":null,"errors":
[{"message":"Cannot query field \"node\" on \"Query\".","locations":
[{"line":1,"column":32}]}]}},"ready":false,"stale":false}` to `{"error":
{"source":{"data":null,"errors":[{"message":"Cannot query field \"node\" on
\"Query\".","locations":[{"line":1,"column":32}]}]}}}`.warning @
app.js:31567update @ app.js:39409onRejected @ app.js:39035tryCallOne @
app.js:30045(anonymous function) @ app.js:30131flush @ app.js:30279
我可以通过使两个视图中的查询片段相同来防止此错误的发生——特别是通过添加 adapter
片段。
然而,这感觉不对。它们不需要完全相同(事实上,由于这对我来说是一个学习应用程序,它们现在有些故意臃肿),其他视图当然不会共享这些数据需求。
- 保持查询声明简洁的最佳做法是什么?
理想情况下,我会让顶级视图只声明顶级数据
要求。具体来说,在我的示例视图文件中,我会请求
只有
viewer
和他们的dataModels
,然后允许 child 组件来表达他们的需求,请求任何嵌套数据(例如categories
、tags
或adapters
及其各自的categories
). invalid state change
错误的真正含义是什么?我可以看到 它对完全匹配的查询感到满意,但我不能 想象不相关的视图需要共享查询声明。我 怀疑这是我在别处做错事的副产品。
谢谢!
当查询发生变化时(例如,由于路由转换或对 setVariables()
的调用),中继将区分您来自的查询和您要去的查询,计算最小值查询让你从 A 到 B。在你的例子中,中继从客户端存储的一系列已知记录(已经获取的记录)开始,并尝试只获取这些确切记录上的新字段,以构建一个完整的世界图景。这些重新获取依赖于一种叫做 node interface.
中继兼容的 GraphQL 服务器必须公开一个名为 node
的根字段,它可以在给定全局 ID 的情况下获取任何记录。该字段必须采用类型为 GraphQLID!
的 id
参数。
有关如何构建此类根字段的示例,请参阅 this graphql-js
example。