Apollo GraphQL javascript react プログラミング

チュートリアルで学ぶApollo Client - Queries -

投稿日:

こんにちは、mabuiです。
前回に続いて今回はApollo ClientのQueryコンポーネントについて、GraphQLからデータを取得してUIに反映させる方法、エラーとローディング状態中の処理方法を見ていきます。
Apollo Clientを使用することで、ローディング中の処理も簡潔に書くことができます。

公式Queryチュートリアルページを部分的に意訳しながら、翻訳した内容になっています。

 

クエリコンポーネント

Queryコンポーネントを作成するには、query属性(=this.props.query)にgql関数でラップしたGraphQLクエリ文字列を渡し、children属性(=this.props.children)にレンダリングする要素を与えます。

children属性に渡された要素は、Queryコンポーネント内部でrender prop関数に渡されてレンダリングされます。

children属性はQueryコンポーネントの要素として定義する必要はなく、コンポーネントの内部に直接置くことができます。

children属性の定義内では、UIのレンダリングに使用できるロード、エラー、およびデータの属性を含むApollo Clientのオブジェクトが提供されます。
下記にselect要素で犬種を選択できるコンポーネントのサンプルコードを記述します。
 

Dogs.js

 

App.js

 


 

DogsコンポーネントをAppコンポーネント内でレンダリングして、selectフォームを表示しています。

フォームの値が変更されると、値がthis.props.onDogSelected経由で親コンポーネントに送信され、以降に出てくるDogPhotoコンポーネントに渡されます。

では、次の章でDogPhotoコンポーネントを構築し、フォームの変数を使ったより複雑なクエリを実行します。

 

データの受け取り

Queryコンポーネントがマウントされると、まずApolloキャッシュからのクエリ結果のロードを試し、そこにない場合はサーバーにリクエストを送信します。

データが戻ってくると、それを正規化してApolloキャッシュに保存します。
Queryコンポーネントは結果をサブスクライブしているため、データをリアクティブに更新します。

Apollo Clientのキャッシュの動作確認のために、DogPhotoコンポーネントを作成します。
DogPhotoコンポーネントはDogsコンポーネントからbreed属性を引き継ぎます。

DogPhoto.js

 

App.js

 


 

onDogSelected関数がDogsコンポーネントに渡され、selectフォームの変更時にselectedDogステートが変更されます。

DogPhotoコンポーネントのbreed属性にはselectedDogステートが渡されて、内部のQueryコンポーネントのvariables属性にそれが渡り、クエリの変数として使用され、ステート変更のたびに犬の画像が変更されます。

犬の画像を選択して、他の犬を選択後に再度最初の犬を選択してみましょう。
(ex. akita → beagle → akita)
同じ犬の選択時に画像の読み込みが発生しないことが分かります。
これは、最初の選択時に画像はApolloのキャッシュに乗るためです!

 

ポーリングと再フェッチ

キャッシュを使用するのではなく、新しいデータが必要な時の手段として、ポーリングと再フェッチがあります。

ポーリングは、クエリを指定された間隔で再取得させることにより、ほぼリアルタイムのデータを取得するのに役立ちます。
ポーリングを実装するには、pollInterval属性をQueryコンポーネントに渡し、間隔をmsで指定します。
0を渡すと、クエリはポーリングしません。
render prop関数に渡される結果オブジェクトに対してstartPolling関数とstopPolling関数を使用して、動的ポーリングを実装することもできます。

 

pollIntervalを500に設定すると、0.5秒ごとに新しい犬の画像が表示されます。 ポーリングは、GraphQLサブスクリプションの設定を複雑にすることなく、ほぼリアルタイムのデータを得る優れた方法です。

ポーリングの代わりにユーザーアクションに応答してクエリを再読み込みする場合はrefetch関数を使用します。 ここでは、DogPhotoコンポーネントにボタンを追加し、クリックするとrefetch関数をトリガーします。 refetch関数はvariables属性を引数に取りますが、新しいvariables属性を渡さないと、以前のクエリのものと同じvariables属性が使用されます。

 

ローディングとエラーステート

再フェッチまたはポーリングを実行しているときのロード状態を取得するには、render prop関数内の結果オブジェクトのnetworkStatus属性を使用して、クエリのステータスに関する細かい情報を取得します。

また、notifyOnNetworkStatusChange属性をtrueに設定して、クエリ再実行中にQueryコンポーネントが再レンダリングするようにする必要があります。

 

networkStatusプロパティは、異なるロード状態を表す1〜8の数値を持つ列挙型です。 4は再フェッチに対応しますが、ポーリングとページ番号の数もあります。 使用可能なすべてのロード状態の完全なリストについては、リファレンスガイドを参照してください。

ロード状態ほど複雑ではありませんが、コンポーネント内のエラーへの応答は、QueryコンポーネントのerrorPolicy 属性を使用してカスタマイズすることもできます。 errorPolicyのデフォルト値は noneで、すべてのGraphQLエラーをランタイムエラーとして扱います。 エラーが発生した場合、Apollo Clientは要求に応じたデータを破棄し、render prop関数のerror属性をtrueに設定します。 エラー情報と共に部分データを表示する場合は、errorPolicyallに設定します。

 

手動でクエリを実行する

ReactがQueryコンポーネントをマウントすると、Apollo Clientは自動的にクエリを実行します。
ユーザーがボタンをクリックするなどのアクションを実行するまでクエリの実行を延期したい場合は、ApolloConsumerコンポーネントを使用し、client.query()を直接呼び出す必要があります。

 

この方法だと冗長になるので、可能な限りQueryコンポーネントを使用することをお勧めします。
 

-Apollo, GraphQL, javascript, react, プログラミング
-, , , ,

Copyright© mabui.org , 2018 All Rights Reserved Powered by STINGER.