開発トラブルシューティング
Next.js Caching and Rendering Troubleshooting
Next.jsのキャッシュとレンダリングに関する問題と解決策
Next.js Caching and Rendering Troubleshooting
このドキュメントは、Next.jsのキャッシュとレンダリングに関する一般的な問題と解決策を記録します。
問題1: 検索パラメータが変更されてもページが更新されない
症状
- URLの検索パラメータ(query string)を変更しても、ページの内容が更新されない
- サーバーサイドのログでは正しいパラメータが渡されているが、UIに反映されない
- ページをリロードすると正しい内容が表示される
根本原因
Next.js 13以降のApp Routerでは、サーバーコンポーネントはデフォルトでキャッシュされます。これにより、同じルートへのナビゲーション時に、以前のレンダリング結果が再利用される場合があります。
解決策
方法1: 動的レンダリングを強制する(推奨)
ページコンポーネントにdynamic設定を追加します。
// ✅ 解決策
export const dynamic = 'force-dynamic';
export default async function MyPage({ searchParams }) {
const params = await searchParams;
const query = params.q;
// クエリパラメータに基づいてデータを取得
const data = await fetchData(query);
return <div>{/* ... */}</div>;
}方法2: revalidateを設定する
特定の時間ごとにキャッシュを無効化します。
// ✅ 代替案(定期的な更新で十分な場合)
export const revalidate = 0; // 常に再検証
export default async function MyPage({ searchParams }) {
// ...
}方法3: キャッシュタグを使用する
より細かい制御が必要な場合は、キャッシュタグを使用します。
import { unstable_cache } from 'next/cache';
const getCachedData = unstable_cache(
async (query) => fetchData(query),
['data-cache'],
{ revalidate: 60 }
);実際の事例: Libraryページの検索機能
状況:
- Libraryページで検索バーに文字を入力しても、結果が更新されない
- サーバーログでは正しくフィルタリングされている
- ページをリロードすると正しい結果が表示される
原因:
// ❌ 問題のあるコード
export default async function LibraryPage({ searchParams }) {
const params = await searchParams;
const query = params.q;
// データを取得してフィルタリング
const items = await fetchAndFilterItems(query);
return <LibraryPageClient initialItems={items} />;
}
// ↑ デフォルトでキャッシュされるため、queryが変わっても再レンダリングされない解決:
// ✅ 解決策
export const dynamic = 'force-dynamic'; // 追加
export default async function LibraryPage({ searchParams }) {
const params = await searchParams;
const query = params.q;
const items = await fetchAndFilterItems(query);
return <LibraryPageClient initialItems={items} />;
}dynamic設定の種類
| 設定値 | 説明 | 使用場面 |
|---|---|---|
'auto' (デフォルト) | Next.jsが自動的に判断 | 通常のページ |
'force-dynamic' | 常に動的レンダリング | 検索、フィルタリング、ユーザー固有のデータ |
'force-static' | 常に静的生成 | 変更されないコンテンツ |
'error' | 静的生成を強制し、動的関数使用時にエラー | 静的生成を保証したい場合 |
ベストプラクティス
-
必要な場合のみ動的レンダリングを使用する
- パフォーマンスのため、可能な限り静的生成を活用
- 検索、フィルタリング、ユーザー固有のデータなど、動的な内容が必要な場合のみ
force-dynamicを使用
-
キャッシュの粒度を適切に設定する
- ページ全体ではなく、特定のデータフェッチのみをキャッシュすることも検討
fetch関数のcacheオプションやnext.revalidateを活用
-
デバッグ方法
- サーバーログでレンダリングのタイミングを確認
- Next.jsの開発モードでは、キャッシュが無効化されることに注意
- 本番環境での動作を確認する
-
関連する設定
// ページレベルの設定 export const dynamic = 'force-dynamic'; export const revalidate = 60; // 60秒ごとに再検証 export const fetchCache = 'force-no-store'; // fetchのキャッシュを無効化
関連する問題
クライアントコンポーネントでの検索パラメータ
クライアントコンポーネントでuseSearchParamsを使用する場合は、自動的に動的レンダリングになります。
'use client';
import { useSearchParams } from 'next/navigation';
export default function ClientComponent() {
const searchParams = useSearchParams();
const query = searchParams.get('q');
// 自動的に動的レンダリング
}参考リンク
最終更新: 2025-11-27
関連タスク: feat-explore-phase7d (Explore/Library/MyWorksページのUI統一)