クライアントを設定する
アプリ全体に 1 つの QueryClient を設定してください。デフォルトを設定し、すべての失敗を 1 か所で報告し、コールバックがスローしたエラーをキャッチします。何かがオブザーバーを作成する前に、main で 1 回だけ設定してください。ウィジェットテストなどでは、アプリの一部を専用のクライアントで動かせます。コンストラクターのすべてのオプションは QueryClient のリファレンスにあります。
クライアントを作成する
Section titled “クライアントを作成する”Fuery.client は、FueryProvider がないときにウィジェットが使うクライアントです。クライアントを渡さなければ、observe() と定義の mutate もこのクライアントを使います。Fuery は最初に使われたときに Fuery.client を作成します。そのため、何も設定しないアプリでも動作します。
設定するには、main で新しいクライアントを代入してください。
void main() { Fuery.client = QueryClient( defaultOptions: const DefaultOptions( queries: QueryDefaults(staleTime: Duration(seconds: 30)), ), ); runApp(const App());}Fuery.clientへの代入は、新しいクライアントをマウントし、前のクライアントをアンマウントします。- マウントされたクライアントは、フォーカス時と再接続時に再取得し、一時停止中のミューテーションを再開します。
- 何かがオブザーバーを作成する前に代入してください。オブザーバーは、作成時のクライアントを使い続けます。
- デフォルトも、オブザーバーができる前に登録してください。オブザーバーはオプションを受け取った時点でデフォルトを適用し、その後は適用しません。
デフォルトを設定する
Section titled “デフォルトを設定する”クライアントのすべてのクエリとミューテーションに対して、またはキーのプレフィックスに対してデフォルトを設定してください。
Fuery.client = QueryClient( defaultOptions: const DefaultOptions( queries: QueryDefaults(staleTime: Duration(seconds: 30)), mutations: MutationDefaults(retry: RetryPolicy.count(2)), ),);
Fuery.client.setQueryDefaults( ['settings'], const QueryDefaults(staleTime: infiniteDuration),);
Fuery.client.setMutationDefaults( ['todos'], const MutationDefaults(networkMode: NetworkMode.offlineFirst),);- クエリやミューテーションに設定したオプションは、キーごとのデフォルトより優先されます。
- キーごとのデフォルトは、クライアントの
defaultOptionsより優先されます。 - ミューテーションにキーごとのデフォルトが適用されるのは、
mutationKeyがある場合だけです。 getQueryDefaults(['settings'])とgetMutationDefaults(['todos'])は、一致するすべてのプレフィックスのデフォルトをマージした、キーごとのデフォルトを返します。defaultOptionsは含みません。
QueryDefaults と MutationDefaults のフィールドの一覧はデフォルトにあります。
すべての失敗を 1 か所で報告する
Section titled “すべての失敗を 1 か所で報告する”キャッシュに設定を渡すと、すべてのクエリとすべてのミューテーションに対してコールバックを実行できます。たとえば、失敗をクラッシュレポートやログのサービスに報告できます。
Fuery.client = QueryClient( queryCache: QueryCache( config: QueryCacheConfig( onError: (error, query) => reportError(error, query.queryKey), ), ), mutationCache: MutationCache( config: MutationCacheConfig( onError: (error, variables, context, mutation) => reportError(error, mutation.options.mutationKey), ), ),);- キャッシュは、存在する間ずっと同じ設定を使います。そのため、設定はクライアントの作成時に渡してください。
QueryCacheConfigのコールバックは、取得の後に実行されます。キャンセルされた取得は失敗ではないので、どのコールバックにも届きません。MutationCacheConfigのコールバックは、ミューテーション自体のコールバックより先に実行されます。コールバックが Future を返すと、Fuery はその Future を待ちます。- コールバックは、ミューテーションの各実行を
AnyCachedMutationとして受け取ります。AnyCachedMutationのdata、variables、contextはObject?です。ミューテーションはmutation.options.mutationKeyかmutation.options.metaで区別してください。
すべてのコールバックとその実行タイミングはキャッシュのコールバックにあります。
コールバックがスローしたエラーをキャッチする
Section titled “コールバックがスローしたエラーをキャッチする”onUncaughtError は、どの呼び出し元もキャッチできない次のエラーを受け取ります。そのため、これらのエラーの記録方法を決められます。
QueryCacheConfigまたはMutateOptionsのコールバックがスローしたエラー- ミューテーションの失敗後に、ミューテーション自体またはその
MutationCacheConfigのonErrorかonSettledがスローしたエラー - クエリの変更後に Fuery がオブザーバーを更新している間に、
refetchWhileかplaceholderDataがスローしたエラー - リスナー(リスナーウィジェット、コンシューマー、フックの
listener、またはスロットのlistenかsubscribeToRunsに渡した関数)がスローしたエラー - Fuery が実行中に見つけた誤り(誤った型のパラメーターを返すか、結果の構築中にスローする
getNextPageParam、保存できない永続化のmutationKeyなど)
Fuery.client = QueryClient( onUncaughtError: (error, stackTrace) => reportError(error, stackTrace),);- クエリやミューテーションは、コールバックがスローしなかったかのように続行します。
- Fuery は、同じ誤りをクライアントごとに 1 回だけ報告します。コードが実行されるたびには報告しません。
onUncaughtErrorがスローすると、そのエラーと受け取ったエラーの両方が現在のゾーンに届きます。
onUncaughtError がないと、これらのエラーは現在のゾーンに届き、Flutter が PlatformDispatcher.onError に渡します。PlatformDispatcher.onError に届いたものをすべて致命的なエラーとして記録するクラッシュレポーターは、これらのエラーをクラッシュとして数えます。実際には、アプリは動き続けています。
Mutation と MutationCacheConfig のそれ以外のコールバックは、ミューテーションの一部です。onMutate、または成功後の onSuccess か onSettled がスローしたエラーは、ミューテーションを失敗させ、その onError に届きます。
クエリが使うクライアント
Section titled “クエリが使うクライアント”Query はクライアントを保持しません。そのため、同じ定義がどのクライアントでも動作します。Fuery は、クエリを使う場所でクライアントを選びます。
- 定義を受け取ったウィジェットやフックは、最も近い
FueryProviderのクライアントを使います。FueryProviderがなければFuery.clientを使います。プロバイダーのクライアントが置き換わると、新しいクライアントに追従します。 observe()は、client:として渡したクライアントか、その時点のFuery.clientを使います。オブザーバーは存在する間ずっとそのクライアントを使い、observer.clientがそのクライアントを返します。- 定義の
mutateとmutateAsyncは、渡したクライアントか、その時点のFuery.clientを使います。ウィジェット内ではcontext.queryClientを渡してください。そうすると、実行がウィジェットの読み取るキャッシュに届きます。 - オブザーバーを受け取ったウィジェットやフックは、オブザーバーのクライアントを使います。デバッグビルドでは、そのクライアントがウィジェットやフック自身のクライアントでない場合に警告を出力します。画面が別のクライアントのキャッシュを読んでいるを参照してください。
- クエリ関数、
placeholderData、ミューテーションのコールバックは、自身を実行するクライアントを受け取ります。
そのため、クエリはトップレベルの値にできます。Fuery.client か FueryProvider でテストごとに新しいクライアントを用意するウィジェットテストでは、ほかに何も必要ありません。
サブツリーに専用のクライアントを持たせる
Section titled “サブツリーに専用のクライアントを持たせる”ウィジェットテストなどでアプリの一部を別のクライアントで動かすには、その部分を FueryProvider で囲んでください。クライアントは State のフィールドに保持してください。そうすると、サブツリーはマウントされている間、同じクライアントを使い続けます。
class _SettingsPageState extends State<SettingsPage> { final client = QueryClient();
@override Widget build(BuildContext context) { return FueryProvider(client: client, child: const SettingsView()); }}- クライアントは 1 回だけ作成してください。作成する場所は
main、Stateのフィールド、またはテストのsetUpです。 build内では作成しないでください。buildで作成したQueryClientは、リビルドやホットリロードのたびに新しい空のキャッシュになります。そのため、下のウィジェットは読み込み中に戻り、再び取得します。FueryProviderはクライアントをマウントし、プロバイダーがなくなるとアンマウントします。そのため、Stateにdisposeは不要です。
プロバイダーの下のウィジェットは、プロバイダーのクライアントを使います。context.queryClient はそのクライアントを返し、プロバイダーがないときは Fuery.client を返します。独自のオブザーバーを作るときは、observe にこのクライアントを渡してください。
late final todos = todosQuery.observe(client: context.queryClient);定義の mutate にも、addTodo.mutate('Buy milk', context.queryClient) のように渡してください。
ほかの状態管理ライブラリ向けのアダプターは、FueryProvider.of(context, listen: true) でクライアントを参照します。この呼び出しを使うと、プロバイダーのクライアントが置き換わったときにリビルドします。
サンプルアプリでは
Section titled “サンプルアプリでは”サンプルアプリは、main でストレージ付きのクライアントを Fuery.client に代入し、runApp の前に保存されたミューテーションを復元します。各画面で何を示しているかは、サンプルアプリの README にまとめています。