使用RelayRouter投掷无效状态更改错误导航relay.js应用程序

Nic*_*hes 1 reactjs react-router graphql relayjs

我正在写一个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);
Run Code Online (Sandbox Code Playgroud)

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,
                    }
                  }
                }
              }
            }
          }
        },
      }
    `,
  },
});
Run Code Online (Sandbox Code Playgroud)

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,
                        }
                      }
                    }
                  }
                }
              },
            }
          }
        },
      }
    `,
  },
});
Run Code Online (Sandbox Code Playgroud)

当间导航DataModelListOrgSetup(在任一方向)我看到在控制台以下错误:

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
Run Code Online (Sandbox Code Playgroud)

我可以通过使两个视图中的查询片段相同来防止发生此错误 - 特别是通过添加adapter片段.

但是,这感觉不对.他们并不需要是相同的(其实他们有些在此刻,因为这对我来说是一个学习的应用程序故意臃肿),以及其他的意见当然不能共享这些数据的需求.

  1. 保持查询声明简洁的最佳做法是什么?理想情况下,我会有顶级视图,只声明顶级数据要求.具体而言,在我的例子视图文件,我会要求只有viewer与他们dataModels,然后让子组件来表达自己的需求,要求任何嵌套的数据(例如 categories,tags或者adapters和他们各自的categories).
  2. 这个invalid state change错误究竟意味着什么?我可以看到它完全符合匹配的查询,但我无法想象共享查询声明需要不相关的视图.我怀疑这是我在其他地方做错事的副产品.

谢谢!

ste*_*her 5

当查询发生变化时(例如,由于路由转换或调用setVariables()),Relay会将您来自的查询和您要查询的查询区分开来,计算最小查询以使您从A到B.你的情况,中继从系列存储在客户端(已牵强的)已知的记录启动并尝试,努力打造世界的全貌获取,只有对那些确切记录的新领域.这些反映依赖于称为节点接口的东西.

符合中继的GraphQL服务器必须公开一个被调用的根域node,可以获取给定全局ID的任何记录.该字段必须采用id类型的参数GraphQLID!.

有关如何构建此类根域的示例,请参阅graphql-js示例.

  • 谢谢你的明确解释.这正是我做错了.我已经定义了一个节点接口但是却愚蠢地忘记了通过root"node"字段将它连接到我的查询. (2认同)