tanstack-integration-best-practices は何をしますか?
TanStack QueryとTanStack Router、TanStack Startを統合するためのベストプラクティス。フルスタックデータフロー、SSR、キャッシュ連携のパターンを提供します。
なぜこれが重要なのか
TanStack Queryはクライアントサイドのデータフェッチとキャッシュに優れていますが、TanStack RouterやTanStack Startと適切に統合しないと、データの重複取得やキャッシュの不整合が発生する可能性があります。このドキュメントは、それらをシームレスに連携させるためのパターンをまとめています。
主要な統合パターン
1. ルーターローダーでのデータプリフェッチ
TanStack Routerのローダー関数内でQueryClientを使用してデータをプリフェッチします。これにより、ルート遷移前にデータがサーバーサイドで準備され、SSR時にHTMLに埋め込まれます。
import { createFileRoute } from '@tanstack/react-router'
import { queryClient } from '../lib/query-client'
import { fetchPosts } from '../api/posts'
export const Route = createFileRoute('/posts')({
loader: async () => {
await queryClient.prefetchQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
})
},
})
2. サーバー関数との統合
TanStack Startのserver$関数を使って、サーバーサイドでのみ実行されるデータ処理を定義し、その結果をQueryのキャッシュに統合します。
import { server$ } from '@tanstack/react-start'
import { queryClient } from '../lib/query-client'
const fetchServerData = server$('fetchData', async () => {
const data = await db.query('SELECT * FROM items')
return data
})
3. キャッシュの連携
QueryClientのキャッシュをルーターの状態と同期させることで、クライアントサイドのナビゲーション時にキャッシュされたデータを再利用し、無駄なAPIコールを削減します。
import { useQuery } from '@tanstack/react-query'
import { useRouter } from '@tanstack/react-router'
export function useSyncedData() {
const router = useRouter()
return useQuery({
queryKey: ['synced-data', router.state.location.pathname],
queryFn: async () => {
const response = await fetch(`/api/data${router.state.location.search}`)
return response.json()
},
})
}
推奨されるアーキテクチャ
- QueryClientの共有: ルーターとアプリケーション全体で同一のQueryClientインスタンスを使用します。
- ローダーでのプリフェッチ: ルートローダー内で必要なデータをプリフェッチします。
- ハイドレーション: SSR時には、サーバーサイドでクエリを解決し、それらをクライアントにハイドレートします。
- 楽観的更新: ミューテーションには楽観的更新パターンを使用し、ルーターの状態と整合性を保ちます。
トラブルシューティング
- キャッシュが古い場合は、QueryClientの
invalidateQueriesメソッドを使用して更新をトリガーします。 - ルート遷移時にデータが再取得されない場合は、ローダーのキーが適切に設定されているか確認してください。