◉GEMINI LABEN
●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止、残り6日。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止、残り6日。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…
記事一覧/API / SDK
◈ API / SDK/2026-04-29上級

Gemini API × TanStack Query でストリーミングUI を本番運用する — キャンセル・再試行・キャッシュ整合の設計

TanStack Query は通常の REST/JSON 用に最適化されており、ストリーミング応答との相性は素直ではありません。 Gemini API のSSEを TanStack Query で扱う際の落とし穴と、本番運用に耐える設計パターンを解説します。

Gemini API248TanStack QueryReactStreamingProduction3

✦ プレミアム記事

Gemini API × TanStack Query でストリーミングUI を本番運用する — キャンセル・再試行・キャッシュ整合の設計

「TanStack Query は便利だから AI チャットの状態管理にも使おう」と思って useMutation で書き始めたものの、ストリーミングが始まった瞬間に手が止まった——そんな経験はないでしょうか。私も最初に試したとき、ストリームの途中経過を画面に出すまでは比較的すぐにできたのですが、ユーザーが連打したときの重複ストリーム、タブ復帰時のリトライ暴走、エラー後の中途半端な表示、と本番で必ず踏む地雷を一つずつ踏んでいきました。

TanStack Query は本来「リクエストを送って JSON が返ってくる」モデル向けに最適化されているライブラリです。ストリーミング応答(SSE や ReadableStream)はその外側にあるため、素直に組み合わせると上手く噛み合いません。ここではGemini API のストリーミングを TanStack Query と統合する際に私が現場で詰まったポイントと、それを解消するための設計パターンを、コピペで動くコード付きで紹介します。

なぜ TanStack Query + ストリーミングは噛み合いにくいのか

TanStack Query が担うのは「同じキーに対するリクエスト結果のキャッシュ・重複排除・再取得」です。前提として「リクエストは一度のレスポンスで完了する」ことが想定されています。一方ストリーミング応答は、複数のチャンクが時間差で届き、途中でキャンセルされる可能性があり、最終結果が「最後のチャンク」ではなく「全チャンクの結合」であるという、根本的に違う性質を持っています。

この性質の違いを理解せずに useQuery で書こうとすると、select で全チャンクを保持しようとして再レンダリングが暴れたり、staleTime の概念が当てはまらず再取得が混乱したりします。私がたどり着いた結論は、ストリーミング自体は useMutation で扱い、確定した結果のみ queryClient.setQueryData でキャッシュに同期する という分離設計です。

データフローを整理するとこうなります。

  • ユーザー入力で mutate() を呼ぶ
  • useMutation の mutationFn 内で ReadableStream を消費する
  • 各チャンクを onChunk 相当のローカル state に流してストリーム表示
  • ストリーム完了時に queryClient.setQueryData(['conversation', id], 全文) でキャッシュに反映
  • 他コンポーネントは useQuery で読み取り

この役割分担にすることで、TanStack Query の強み(キャッシュ・無効化・楽観的更新)はそのまま使いつつ、ストリーミング特有の制御は通常の React state で扱えるようになります。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦TanStack Query の useMutation + ReadableStream で詰まっていた人が、キャンセル・再試行・部分結果保持まで含む完成形のコードを今日手に入れられる
✦ストリーミングの途中で switchTab → refocus が起きたときに発生する重複ストリーム・メモリリークを、queryClient と AbortController で正しく制御する設計を習得できる
✦本番でユーザーが連打したり接続が切れたりする状況でも、UI が壊れず途中までの応答を保持し、サーバー側のトークン消費も最小化する運用パターンに切り替えられる
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

◈ API / SDK2026-10-14
config に「Extra inputs are not permitted」が出たら、キーの綴りを一つずつ疑います
google-genai SDK で config を渡した途端に pydantic の ValidationError(extra_forbidden)が出る原因は、ほぼ綴りの一字違いです。手元で再現した出力と、呼び出し前に怪しいキーを洗う関数、text が None になる場合の見分け方を書き残します。
◈ API / SDK2026-10-08
停止日のない非推奨をどう扱うか — 画像モデルの移行先を、3つの条件で選び直す
10月6日に gemini-nano-banana-2.1 が GA になり、gemini-3.1-flash-image は停止日の書かれないまま非推奨になりました。解像度・参照画像・検索の3条件で移行先を選ぶ表と、確認用の短いスクリプトをまとめます。
◈ API / SDK2026-09-29
『F6号』と『A4くらい』が同じ列に並ぶ作品台帳を、Gemini の読み取りと号数表の換算で cm に揃えるまで
作家さんの作品台帳に『F6号』『41×31.8cm』『A4くらい』が混ざっていました。Gemini API には読み取りだけを頼み、換算は号数表、向きは画像で決める小さな道具を、動くコードとともに一本ずつ組み立てます。