React Hook Form + MUI Autocomplete で絞り込み検索機能付きのプルダウンリストを作ってみた

React Hook Form v7 と MUI v5(Autocomplete コンポーネント)を利用してフィルター検索機能付きのプルダウン(ドロップダウン)リストを作ってみました。
2022.07.07

React を触り始めてからそろそろ1年くらいの下田です。

沢山ある選択肢の中からいくつかのデータを指定するようなケースにおいて、ユーザーが延々とプルダウンリストをスクロールしたり、大量のデータの中から目的とする選択肢を目視で探すという状況は非常に辛いものがあります。また、そういった UI が提供された場合に利用者の立場で考えると体験があまりよろしくないというのは容易に推測できます。

Web アプリ開発を始めたばかりの頃(の私)は漠然と、「絞り込み検索機能付きのプルダウンリストって作るのが難しいんだろうなぁ」と考えておりましたが MUI(旧名称:Material UI)の Autocomplete というコンポーネントを利用すると頑張らずに実装できることが分かりました。

そこで今回は、react-hook-form v7 と組み合わせた絞り込み検索機能付きのプルダウンリストの実装サンプルをご紹介したいと思います。

なお、ソースコードは下記の GitHub リポジトリで公開しております。

サンプル

実際に触ってみていただいた方が分かりやすいと思いますので、CodeSandbox を利用して公開しているサンプルフォームを掲載します。

プルダウンの選択肢(データ)は、MUI Autocomplete のサンプルコードから拝借しております(映画の題名)

Single Select は、1つ映画が選択できます。例えば、テキスト入力フィールドへ Toy と入力すると "Toy Story 3" と "Toy Story" の2つのタイトルが絞り込まれることが確認できます。(実際に試してみてください)

ToyStory.png

Multi Select は複数選択可能なプルダウンリストになっています。 また、CONFIRM ボタンをクリックするとフォームで入力されたデータ(JSON)がダイアログウィンドウで表示されます。

コードの紹介

Single Select のプルダウンリストを生成するコードは、18行ほど

single-640x426.png

Controller コンポーネントは、react-hook-form からインポートされたラッパーコンポーネントです。render prop に Autocomplete コンポーネントを指定することでイベントおよび入力値を react-hook-form にアタッチします。

Autocomplete コンポーネントが今回のメインです。options には、プルダウンリストの元データとなる配列(サンプルでは、top100Films)を指定します。また、renderInput に TextField コンポーネントを指定することで、テキスト入力可能なプルダウンリストをレンダリングします。

最後に onChange へプルダウンリストから値が選択(変更)された際の動作として react-hook-form の setValue() を利用し single フィールドへ指定された値を設定します。

実際に、プルダウンからタイトルを指定するとサンドボックスの右側に配置された DevTool の表示が更新されることを確認できると思います。

タイトル選択前

DevTool.png

タイトル選択後

DevTool1.png

Multi Select の方は、下記2項目を変更すると動作します。

  • Autocomplete コンポーネントに multiple Prop を指定する
  • フォームの入力フィールドを配列で初期化(本記事では、react-hook-form の multi フィールドに初期値として [] を指定しています)

複数タイトルを指定すると、下記のような表示になります。

MultiSelect-640x283.png

最後に、COMFIRM ボタンをクリックすると入力したデータがダイアログで表示されます。

Dialog-640x688.png

20行程度のコード量で、絞り込み検索機能付きのプルダウンリストが実装できていることが確認できました。

さいごに

MUI Autocomplete コンポーネントや React Hook Form など素晴らしいライブラリを活用することにより、少ないコード量で実装できることが確認できました。

機会があれば MUI Autocomplete コンポーネントを活用してみてはいかがでしょうか。

ではでは