🍎
nextjsで絞り込み検索の体験向上
はじめに
nextjsのチュートリアルを進めていて参考になる章があったのでまとめてみました。
こちらの3点を要件とします。
- 検索ボックスに入力したらボタンをクリックまたはEnterキーを押さなくても自動で反映してほしい。
- 反映する前は一時的にローディングuiを表示したい。
- ページネーションを実装したい
今回開発する画面はこちらになります。
検索部分
- 検索文字が入力された時の関数
const handleSearch = useDebouncedCallback((term) => {
const params = new URLSearchParams(searchParams);
params.set("page", "1");
if (term) {
params.set("query", term);
} else {
params.delete("query");
}
replace(`${pathname}?${params.toString()}`);
}, 300);
term: 入力された文字
params.set(“query”, term)で入力内容をセットし、
replace(${pathname}?${params.toString()}
);でページ遷移しています。
useDebouncedCallbackは呼び出しから一定時間経たないと処理を実行しないreactのカスタムフックです。例えば「ABC」と入力した時にこのような違いがあります。
- デバウンスなし
入力内容が「A」→処理実行→「AB」→処理実行→「ABC」→処理実行 - デバウンスあり
入力内容が「A」→「AB」→「ABC」→0.3秒待機→処理実行
これを入れることでサーバーの負担も少なくなり、ユーザー目線も画面がチラつくことがなくなります。
- 一時的なuiを表示する部分
<Suspense key={query} fallback={<InvoicesTableSkeleton />}>
<Table query={query} currentPage={currentPage} />
</Suspense>
ここはreact標準のSuspenseコンポーネントを使用。
<Suspence>は子コンポーネントが読み込み中の間にローディングコンポーネントなどの一時的なuiを表示します。
今回はqueryが変化するごとに<InvoicesTableSkelton>を一時的に表示しました。
そしてこのような画面になります。(gif)
ページネーション部分
const query = searchParams?.query || "";
const currentPage = Number(searchParams?.page) || 1;
const totalPages = await fetchInvoicesPages(query);
queryが変更されると合計のページ数をフェッチ
const allPages = generatePagination(currentPage, totalPages);
const createPageURL = (pageNumber: number | string) => {
const params = new URLSearchParams(searchParams);
params.set("page", pageNumber.toString());
return `${pathname}?${params.toString()}`;
};
return (
<>
<div className="inline-flex">
<PaginationArrow
direction="left"
href={createPageURL(currentPage - 1)}
isDisabled={currentPage <= 1}
/>
{allPages.map((page, index) => {
return (
<PaginationNumber
key={`${page}-${index}`}
href={createPageURL(page)}
page={page}
/>
);
})}
ページネーションの矢印など数字のボタン部分のリンクをcreatePageURLで作成
ページネーションが実装されました(gif)
nextjsのチュートリアル
nextjsの勉強をするならチュートリアルがおすすめです。

NCDC株式会社( ncdc.co.jp/ )のエンジニアチームです。 募集中のエンジニアのポジションや、採用している技術スタックの紹介などはこちら( github.com/ncdcdev/recruitment )をご覧ください! ※エンジニア以外も記事を投稿することがあります
Discussion