※初心者のため、間違いや何かご存じの方がいましたら、教えていただけると助かります。
作ったもの
今回の内容
アプリ内で剣先機能を2か所(商品名検索、成分検索)実装して、手順が理解できたため整理します。
環境
windows11
docker-desktop
Next.js(app routerを使用)
supabase
ホスティング:Vercel
手順
1. page.tsxにuseState()で、検索語を保持する。初期値は空文字("")
const コンポーネント名 = () => {
...
const [searchTerm, setSearchTerm] = useState("");
...
2. returnの中に、検索する語句を入力するための入力タグ(inputタグ)を作成する。
onChange={(e) => setSearchTerm(e.target.value)とすると、検索語を入力するたびに検索・抽出が実行される。もし、🔍ボタンを押したときのみ実行したいなら、buttonタグを別に作って、onClickから、(e) => setSearchTerm(e.target.value)を呼び出すようにする。
<input
className={styles.input}
type="text"
placeholder="検索ワードを入力"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
3. 検索対象のlistsを、検索語でフィルタリングした、filteredList(変数。名前はなんでもよい)を作成する。
const filteredLists = lists.filter((item) =>
item.A.includes(searchTerm) //Aには、検索語で対象にするプロパティ名(データベースの列名)を入れる。
);
4. return内のlists.map~の記述で、lists → filteredListsに変更する。
{filteredLists.map((product) => (
<Link>
{product.A}
</Link>
))}
これで、検索語が変更されるたびに、リストフィルタリングされたものが画面上に表示される。
なおアプリ内で、商品に成分を登録するページにも実装したが、チェックボックスのチェック有無は変更されなかった。(チェックしたものが、検索後に外れることは無かった。)
あくまで、「プラウザの見た目上で」フィルタリングされる(見えなくなる)だけだと思われる。
まとめ
今回のアプリでは、リストを全部取得したうえで検索する機能としたため、想像以上に簡単かつ、高速だった。
ただし、リストをクライアントに全部渡さずに表示させる場合は、データベース(今回はsupabase)からデータを取得する段階で条件指定しなければならないと思われる。
なお、今回設定しなかったが、検索に一致するものが無かった場合は、{!filteredLists ? "一致なし" : filteredLists.map(()=>... }などとして、ユーザーに「一致が無かったこと」を伝えたほうが良さそう。
次回は、return内のテーブルセルの値によって、セルの色を変えるように、CSSで条件分岐した方法についてまとめておきたい。