なぜ私のフィールドは null なのか?
Relay によってリードされるフィールドが null になる理由は数多くあります。その一部はわかりにくいか、直感に反するものがあります。予期せず null 値をデバッグする場合は、フィールドが null としてリードされる可能性のある一般的なケースとエッジケースの両方理解すると役立ちます。このドキュメントでは、null または欠落値につながる可能性のあるケースを列挙し、現在どのケースにあるかを判断するためのヒントを提供します。
サーバーが Null を返した
フィールドが null になりうる最も単純な理由は、サーバーが明示的に null を返したことです。これは 2 つのケースで発生する可能性があります
- サーバーの field resolver が明示的に null を返した
- field resolver がスローされます。この場合、GraphQL はそのフィールドに対して null を返します。サーバーリゾルバーの戻り値の型が非 null であっても、これは true です。 唯一の例外は非 null として注釈付けされたフィールドです。その場合、サーバーは 決して null を返すべきではありません。例外が発生した場合、親オブジェクト全体が null になります。
🕵️♀️ 確認方法: Relay Dev ツールまたはブラウザの開発ツールのネットワークタブを使用してサーバーの応答を調べ、フィールドが null かどうかを確認します。
グラフの関連性の変更
別のクエリ/ミューテーション/サブスクリプションがグラフ内の関係性の変更を観測した場合、クエリでフェッチしていないオブジェクトからフィールドを読み取ろうとする可能性があります。
親友の名前を読み取るクエリがあると想定します
query MyQuery {
me {
best_friend {
# id: 1
name
}
}
}
クエリレスポンスを取得した後、サーバー上の親友が誰であるかが変更されます。次に、別のクエリ/ミューテーション/サブスクリプションが best_friend
から別のフィールドセットをフェッチします。
query OtherQuery {
me {
best_friend {
# new id: 2
# Note: name is not fetched here
age
}
}
}
Relayストアは正規化されているため、best_friend
のリンクされたフィールドがIDが2のユーザーを指すようになったことを示すme
レコードを更新し、私たちはそのユーザーに関する唯一の情報を、その年齢だということを知っています。
これによりMyQuery
の再描画がトリガーされます。ただし、IDが2のユーザーからname
フィールドを読み取ろうとすると、IDが2のユーザーに関する唯一の情報がそのage
なので、そのフィールドは見つかりません。この場合の関係の「変更」は、新しい関係も意味している可能性があることに注意してください。たとえば、親友がいなくて、その後のレスポンスで親友が некоторых返されたが、コンポーネントに必要なすべてのフィールドがフェッチされていない場合などです。
メモ:理論的には、この状態が発生した場合にRelayはクエリを再フェッチ可能性がありますが、一部のクエリは恣意的に再発行するのは安全ではなく、より一般的には、直接ユーザーアクションに関連していない方法でのUI状態の変更は混乱を招く可能性があります。このため、このようなシナリオでは再フェッチは実行しないことを選択しました。
🕵️♀️ やり方:FragmentResource
のreadWithIdentifier
の最後のreturn文にブレークポイント/console.log
を配置できます (コードポインター). これは、データが不足していることがRelayに認識されますが、それを取得するクエリが進行していない地点です。
一貫性のないサーバーレスポンス
これはまれなエッジケースですが、それでもサーバーがid
フィールドのフィールドの安定性セマンティクスを正しく実装していない場合、レスポンスのある部分にフィールドが表示されるが、別の部分にはnullと明示的に表示される可能性があります。
{
me {
id: 1
name: "Alice"
}
me_elsewhere_in_the_graph {
id: 1 # Note this is the same as the `me` field above...
name: null
}
}
このような場合、Relayは最初にユーザー1のname
はAliceであることを認識しますが、クエリの後半でユーザー1のname
はnull
になっていることを検出します。Relayはデータを正規化されたストアに保存するため、ユーザー1はname
に対して1つの値しか持つことができず、Relayはユーザー1のname
がnull
の状態になります。
🕵️♀️ やり方:Relayはこれが発生したことを検出するのに十分賢く、デベロッパー向けのコンソールに以下のようなエラーを記録します「RelayResponseNormalizer: 無効なレコード。このレコードには同じidのインスタンスが2つ含まれています。1つは競合するフィールド、name、その値がAliceとnullです。」さらに、クエリレスポンスを手動で調査することもできます。
不安定なフィールドがリンクされたフィールド(別のオブジェクトへのエッジ)である場合、この種類のバグにより(上で説明した)グラフの関係の変更が単一のレスポンス内で発生する可能性があることに注意してください。たとえば、同じid
を持つユーザーがレスポンスに2か所表示されるが、それらの2つの場所のbest_friend
が異なる場合などです。
🕵️♀️ やり方:Relayはこのケースも検出するのに十分賢く、デベロッパー向けのコンソールに同様の警告を表示します。
クライアント側の削除または不完全な更新
権限のあるストアのアップデート、または楽観的なアップデートでレコードまたはフィールドが削除された可能性があります。権限のあるストアのアップデート、または楽観的なアップデートで新しいレコードがストアに書き込まれる場合、読み取り可能であると期待されるフィールドに値を提供しない可能性があります。これは根本的な問題です。なぜなら、更新プログラムは新しいオブジェクトからアクセスされる可能性のあるすべてのデータを静的に知ることはできないからです。
🕵️♀️ 判断する方法: ReactおよびRelayのバッチ処理のため、コンポーネントのアップデートを、それをトリガーしたストアのアップデートに関連付けることは常に可能ではありません。この場合、値がnullのときにコンポーネントにブレークポイントを設定し、Relay Devツールを使用して、最新のアップデートを確認することをお勧めします。
これは、特定のフィールドを提供していない新規作成オブジェクト、またはグラフ内の新しいまたは変更されたリレーションシップを引き起こす更新によって発生する場合があります。この場合は、そのセクションの「判断する方法」のヒントを使用してください。
このページは役に立ちましたか?
次の方法でサイトをさらに向上させるのに役立ててください 簡単な質問に答えてください.