1

私は 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

2 つのビューのクエリ フラグメントを同一にすることで、特にフラグメントを追加することで、このエラーの発生を防ぐことができますadapter

しかし、これは間違っているように感じます。それらは同一である必要はありません (実際、これは私にとって学習アプリであるため、現時点では意図的に肥大化しています)。もちろん、他のビューはこれらのデータのニーズを共有しません。

  1. クエリ宣言を簡潔に保つためのベスト プラクティスは何ですか? 理想的には、トップレベルのビューでトップレベルのデータ要件のみを宣言するようにします。具体的には、私の例のビュー ファイルでは、viewerとそののみを要求しdataModels、子コンポーネントがニーズを表現できるようにして、ネストされたデータを要求します (例: categoriestagsまたはadaptersとそれぞれのcategories)。
  2. invalid state changeエラーの本当の意味は何ですか? クエリが正確に一致することで満足していることはわかりますが、クエリ宣言を共有するために無関係なビューが必要になるとは思えません。これは、私がどこかで間違ったことをしたことの副産物だと思います。

ありがとう!

4

1 に答える 1

5

クエリが変更されると (例: ルート遷移または への呼び出しによりsetVariables())、Relay は、元のクエリと先のクエリを比較し、A から B に到達するための最小限のクエリを計算します。あなたの場合、Relay は、クライアントに保存されている一連の既知のレコード (既に取得されたもの) から開始し、世界の全体像を構築するために、それらの正確なレコードの新しいフィールドのみを取得しようとします。これらの再取得は、ノード インターフェイスと呼ばれるものに依存しています。

リレー準拠の GraphQL サーバーはnode、グローバル ID を指定して任意のレコードをフェッチできるルート フィールドを公開する必要があります。このフィールドidは type の引数を取る必要がありますGraphQLID!

このようなルート フィールドを構築する方法の例については、このgraphql-jsを参照してください。

于 2016-03-09T14:21:24.987 に答える