React NativeでのReact Query活用方法: データ取得、キャッシング、パフォーマンスの最適化(Part 2)

著者:Nguyen Thanh Phuong ーソフトウェアエンジニア、 Atlantic Team

Part1では、ReactおよびReact Nativeアプリケーションでサーバー状態を管理するための強力なライブラリであるReact Queryを簡単に紹介しました。React Queryはデータの取得、キャッシング、同期、および更新を簡素化し、非同期処理を処理して一貫したUI状態を維持するためのシームレスな方法を提供します。Part 2では、アプリケーション内でReact Queryを実装し、そのアーキテクチャについて詳しく説明します。React Queryの主要なコンポーネントがどのように連携してデータ管理を最適化し、アプリのパフォーマンスとユーザー体験を向上させるかを解説します。

(Part 1の記事はコチラ

インストール

ステップ1: React Nativeプロジェクトのセットアップ

React Nativeプロジェクトをセットアップしていない場合は、新しいプロジェクトを作成するためにnpx react-native initを使用するか、簡単なセットアップのためにexpoを使用することができます。

React Native CLIを使用する場合:

 


Expo CLIを使用する場合:

ステップ2: 依存関係のインストール

@tanstack/react-queryと、React Queryの開発ツール(任意ですが推奨)をインストールする必要があります。

推奨事項
コードを書く際にバグや不整合を発見するのに役立つESLintプラグイン「Query」の使用も推奨されます。以下のコマンドでインストールできます。

ステップ3: プロジェクトでReact Queryをセットアップ

React Queryクライアントを作成:
まず、プロジェクト内でクエリクライアントを作成します。これを別のファイル(例: src/config/react-query.js)に作成することができます。

アプリにクエリクライアントを提供:
アプリ全体にクエリクライアントを提供するために、アプリケーションのルートコンポーネントを QueryClientProvider でラップします。

ステップ4: React Queryを使用してデータを取得する

これで、React Queryを使用してコンポーネント内でサーバーの状態を取得および管理できます。

1. データ取得関数の作成

APIからデータを取得するための関数を作成します。この関数は、src/api.jsのような別のファイルに配置することができます。

2. useQuery Hookを使用

useQueryフックを使用してデータを取得し、ローディング状態とエラー状態を管理します。


useQueryフックを使用する際には、少なくとも2つのパラメーターを渡す必要があります。

  • 最初のパラメーターは「クエリキー」で、`string[]`型です。これはデータの再取得、キャッシング、およびコンポーネント間でのデータ共有に使用されます。
  • 2番目のパラメーターは、通常APIを呼び出すために使用される関数です。この関数はPromiseを返し、データを解決するかエラーを投げることができます。
  • 残りのパラメーターはオプションです。

useQueryは、データやisFetchingisErrorなどの必要な情報を返します。これらの情報を使用して、適切な状態を表示します。


以下は、アプリケーション内のデータフローを視覚化した図です。

3. コンポーネントの統合:
最後に、作成したTodosコンポーネントをアプリに統合します。


ステップ5: プロジェクトの実行

プロジェクトを実行して、React Queryの動作を確認しましょう。

これでReact QueryをReact Nativeアプリケーションに正常に統合できました。[“todos”]というキーを持つクエリには、2日間のキャッシュ時間が設定されています。つまり、データはキャッシュ内に2日間保存されます。この画面にアクセスすると、キャッシュされたデータがすぐに表示されます。さらに、このクエリのデータは4時間新鮮な状態が保たれ、4時間後にはデータが古い(stale) とマークされ、必要に応じて再取得が可能になります。

React Queryアーキテクチャー

クエリコア

  • QueryClient:
    クエリのデフォルト設定オプション(例: gcTimestaleTimeretryなど)は QueryClient 内に保持されます。
  • QueryCache:
    すべてのクエリを保持し、それらの状態を管理し、ガーベージコレクションなどの機能を提供します。
  • Query:
    各クエリを表し、それぞれのクエリのデータと状態を保持します。
  • QueryObserver:
    クエリの変更を監視し、変更があればReactコンポーネントを更新します。
  • QueryClientProvider:
    Reactコンポーネントツリーに QueryClient を提供し、useQuery などのフックでアクセスできるようにします。

フレームワーク固有(Reactコンポーネント)

  • useQuery
    このフックはReactコンポーネント内でデータを取得し、管理するために使用されます。QueryObserverインスタンスを作成し、対応するクエリにサブスクライブします。
  • queryKey
    クエリを一意に識別し、キャッシュや管理を効率的に行えるようにします。
  • Component
    useQueryフックを使用してデータを取得し、それをレンダリングするReactコンポーネント。

外部ストレージ

クエリキャッシュを外部ストレージと同期するPersistersがあります。例えば、localStorageなどを使用してキャッシュを永続化し、アプリケーションのライフサイクルを超えてデータを保持し、次回のアプリケーション読み込み時にデータを復元できるようにします。

仕組み

  1. 初期化:
    • QueryClient はデフォルトオプションで初期化されます。
    • QueryClientProvider は、コンポーネントツリーに QueryClient を提供します。
  2. データの取得:
    • コンポーネントが useQuery フックを queryKey と共に使用すると、QueryObserver が作成されます。
    • QueryObserver は、QueryCache 内の対応するクエリにサブスクライブします。
  3. クエリの状態管理:
    • QueryCache は複数のクエリを保持し、それぞれが異なるデータ取得リクエストを表します。
    • これらのクエリの状態(ロード中、成功、エラー)は QueryClient によって管理されます。
  4. コンポーネントの更新:
    • QueryObserver はクエリ状態の変更をコンポーネントに通知し、必要に応じて再レンダリングを行います。
    • これにより、コンポーネントは最新のデータを常に取得でき、手動で状態を管理する必要がなくなります。
  5. 外部ストレージ:
    • QueryCachePersisters を介して外部ストレージと同期でき、クエリデータを永続化します。
    • これにより、アプリが再読み込みされた際にキャッシュを復元し、不要なデータ取得を削減できます。

まとめ:

      • QueryClient はすべてのクエリのグローバル状態を保持・管理します。
      • QueryCache は個々のクエリとその状態を保持します。
      • QueryObserver はクエリとコンポーネントをリンクし、クエリの状態が変わるとコンポーネントを更新します。
      • useQuery フックは、コンポーネントがデータを取得し利用するための主要な手段であり、QueryClientQueryCache を活用します。
      • 外部ストレージはキャッシュを永続化し、セッション間でデータを保持できます。

まとめ

このブログでは、React NativeアプリケーションにReact Queryを統合する方法を説明しました。プロジェクトのセットアップ、必要な依存関係のインストール、クエリクライアントの作成と提供、そしてuseQueryフックを使用してデータを取得および管理する手順をカバーしています。また、React Queryが提供するキャッシング、リアルタイム更新、エラーハンドリングといった複雑なデータ取得シナリオにおける利点にも焦点を当てています。さらに、React Queryのアーキテクチャ(QueryClientQueryCacheQueryObserver など)がどのように連携してクエリ状態を管理し、効率的にコンポーネントを更新するかについても解説しました。

Facebook Like Button