あかね
mui/Autocompletの実装
2024年11月29日
要約を生成中...
はじめに
以前にフロントエンド実装をやらせていただいた実務案件で、オートコンプリートの実装が要件になっていることがありました。
オートコンプリートって何? ?オイシイの?レベルから、なんとか実装しました(もう2ヶ月くらい前・・?)。印象には残っているもののあまり覚えていなかったので、復習も兼ねて備忘録としてまとめてみます。
どこかで見たことあるような機能だったので、オリアプではあんまりないかもしれないですが実務では使用すること多そうだなという印象でした。(シランケド)
オートコンプリートとは
入力フィールドに文字を入力すると、候補が自動的に絞り込まれて表示される機能です。
セレクトボックスが検索窓になっているような感じのやつです。
選択肢がズラッとでる。絞り込みも出来る。という便利な機能です。
使用したライブラリ
material-uiを使用しました。
このライブラリを使うようにとか特に決まりはなくて、やりやすいように使い慣れているライブラリつかっていいしデザインもこだわりなしって感じでとてもやりやすかったのですが、ググったところmaterial-uiがヒットしてやりやすそうだなと感じたので使うことにしました。
実装する方法
全然関係ないんですけど、今まで既存のプロジェクト使って新たに書くコードは最低限に粘ってきたんですけど、今回さすがにブログ用のプロジェクト作ることにしましたw
インストール
material-uiとreact-hook-formをインストールします。
npm install @mui/material @emotion/react @emotion/stylednpm install react-hook-formフォームの状態を管理するためにreact-hook-formも使用します。
コード書く
"use client";
import { Autocomplete, TextField } from "@mui/material";
import { useForm, Controller } from "react-hook-form";
export const SampleAutocomplete: React.FC = () => {
const { control } = useForm<{ beer: { label: string; id: number } | null }>();
const options = [
{
label: "スーパードライ",
id: 1,
},
{
label: "プレモル",
id: 2,
},
{
label: "バドワイザー",
id: 3,
},
{
label: "エビス",
id: 4,
},
{
label: "一番搾り",
id: 5,
},
];
return (
<Controller
name="beer"
control={control}
defaultValue={null}
render={({ field }) => (
<Autocomplete
{...field}
options={options}
getOptionLabel={option => option.label}
renderInput={params => (
<TextField {...params} label="ビールの種類" required />
)}
onChange={(_, data) => field.onChange(data)}
isOptionEqualToValue={(option, value) => option.id === value?.id}
/>
)}
/>
);
};解説
インポート
import {Autocomplete,TextField} from '@mui/material';
import { useForm, Controller } from "react-hook-form";オートコンプリートで必要なのは、@mui/materialからAutocompleteとTextField。
react-hook-formからuseFormと Controllerです。
useFormをセットアップ
const { control } = useForm<{ beer: { label: string; id: number } | null }>();選択項目を定義
const options = [
{
label: "スーパードライ",
id: 1,
},
{
label: "プレモル",
id: 2,
},
{
label: "バドワイザー",
id: 3,
},
{
label: "エビス",
id: 4,
},
{
label: "一番搾り",
id: 5,
},
];選択する項目は通常はAPIで取得したデータをlabelとid等、オートコンプリートで使える形に整形してから使用しますが、今回サンプルデータで実装したので直接定義しました。
私はスーパードライ派です
Controllerコンポーネント
<Controller
name="beer"
control={control}
defaultValue={null}name:フォームのフィールド名。control:useFormから取得したcontrolオブジェクトdefaultValue:初期値にnull
Autocompleteコンポーネント
render={({ field }) => (
<Autocomplete
{...field}
options={options}
getOptionLabel={option => option.label}
renderInput={params => (
<TextField {...params} label="ビールの種類" required />
)}
onChange={(_, data) => field.onChange(data)}
isOptionEqualToValue={(option, value) => option.id === value?.id}
/>
)}{...field}:Controllerから渡されるfieldオブジェクトを展開し、valueやonChangeなどのイベントハンドラをAutocompleteに渡す。これにより、React Hook Formが
Autocompleteの入力値を管理できるoptions:選択肢の配列。labelとidを持つオブジェクトの配列として定義。getOptionLabel:各選択肢のlabelを表示する関数。optionsのlabelを取得して表示renderInput:TextFieldをレンダリングするための関数。paramsにはAutocompleteが必要とするプロパティが渡され、label="ビールの種類"を指定。onChange:Autocompleteの選択が変更されたときにReact Hook FormのonChangeを呼び出し、フォームの値を更新。(_, data)で受け取ったdataが選択されたオプション。isOptionEqualToValue:選択肢と現在の値を比較するための関数。オプションと現在の値が同じかどうかを
idで比較し、一致する場合に選択状態を正しく反映する。これにより、すでに選択済みの値がオプションとして認識され、リストが適切に絞り込まれる。
仕上がり
表示された内容から選択できて
検索もできます。
動画撮ったけど貼り方わからず。スクショですみませんw
おわりに
この案件でmaterial-uiを初めて使いましたが、CSS苦手でも簡単にいい感じのUIができて感動しました。
今回は自分の復習のためでしたが、使う機会があれば参考にしてください。

