概要
ページネーションは、大量のデータをページ単位に分割して表示・取得する設計パターンです。
limit(1ページの件数)と offset(何件目から取得するか)の2つのパラメータで実装するのが一般的です。
基本計算
const PAGE_SIZE = 20;
const currentPage = 3; // 1始まり
const offset = (currentPage - 1) * PAGE_SIZE; // 40
const limit = PAGE_SIZE; // 20
const totalPages = Math.ceil(totalCount / PAGE_SIZE);
URL クエリでページを管理する
Next.js App Router では URL クエリにページ番号を持たせると、ブラウザ履歴と同期できます。
// /samples?page=2
export default async function Page({ searchParams }) {
const page = Number(searchParams.page ?? 1);
const { items, total } = await fetchItems({ page, limit: PAGE_SIZE });
return (
<>
<ItemList items={items} />
<Pagination currentPage={page} totalPages={Math.ceil(total / PAGE_SIZE)} />
</>
);
}
よくある落とし穴
絞り込み条件を変えたときにページ番号をリセットしないと、2ページ目以降で意図しない範囲が表示されます。
// フィルタ変更時は page を削除してリセット
const params = new URLSearchParams(searchParams.toString());
params.set("framework", newFramework);
params.delete("page"); // ← 忘れがち
router.push(`/samples?${params.toString()}`);
カーソルベースとの比較
offset/limit はシンプルですが、大量データのページスキップには不向きです。 SNS の無限スクロールなど大量データ向けにはカーソルベース(keyset)ページネーションが適しています。