mui/Autocompletの実装

mui/Autocompletの実装

投稿日: 2024年11月29日

学習振り返り
要約
  • オートコンプリート機能を実装するためにMaterial-UIとReact Hook Formを使用した。
  • オートコンプリートは入力フィールドに対して候補を自動的に表示し、選択肢を絞り込む便利な機能である。
  • 実装は簡単で、CSSが苦手でも良いUIが作れることに感動した。

はじめに

以前にフロントエンド実装をやらせていただいた実務案件で、オートコンプリートの実装が要件になっていることがありました。

オートコンプリートって何? ?オイシイの?レベルから、なんとか実装しました(もう2ヶ月くらい前・・?)。印象には残っているもののあまり覚えていなかったので、復習も兼ねて備忘録としてまとめてみます。

どこかで見たことあるような機能だったので、オリアプではあんまりないかもしれないですが実務では使用すること多そうだなという印象でした。(シランケド)

オートコンプリートとは

入力フィールドに文字を入力すると、候補が自動的に絞り込まれて表示される機能です。

セレクトボックスが検索窓になっているような感じのやつです。

mui/Autocompletの実装装|ShiftBブログ

選択肢がズラッとでる。絞り込みも出来る。という便利な機能です。

使用したライブラリ

material-uiを使用しました。

このライブラリを使うようにとか特に決まりはなくて、やりやすいように使い慣れているライブラリつかっていいしデザインもこだわりなしって感じでとてもやりやすかったのですが、ググったところmaterial-uiがヒットしてやりやすそうだなと感じたので使うことにしました。

実装する方法

全然関係ないんですけど、今まで既存のプロジェクト使って新たに書くコードは最低限に粘ってきたんですけど、今回さすがにブログ用のプロジェクト作ることにしましたw

インストール

material-uiとreact-hook-formをインストールします。

npm install @mui/material @emotion/react @emotion/styled
npm 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:フォームのフィールド名。

  • controluseFormから取得した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オブジェクトを展開し、valueonChangeなどのイベントハンドラをAutocompleteに渡す。

    これにより、React Hook FormがAutocompleteの入力値を管理できる

  • options:選択肢の配列。labelidを持つオブジェクトの配列として定義。

  • getOptionLabel:各選択肢のlabelを表示する関数。optionslabelを取得して表示

  • renderInputTextFieldをレンダリングするための関数。paramsにはAutocompleteが必要とするプロパティが渡され、label="ビールの種類"を指定。

  • onChangeAutocompleteの選択が変更されたときにReact Hook FormonChangeを呼び出し、フォームの値を更新。(_, data)で受け取ったdataが選択されたオプション。

  • isOptionEqualToValue:選択肢と現在の値を比較するための関数。

    オプションと現在の値が同じかどうかをidで比較し、一致する場合に選択状態を正しく反映する。これにより、すでに選択済みの値がオプションとして認識され、リストが適切に絞り込まれる。

仕上がり

表示された内容から選択できて

mui/Autocompletの実装装|ShiftBブログ

検索もできます。

mui/Autocompletの実装装|ShiftBブログ

動画撮ったけど貼り方わからず。スクショですみませんw


おわりに

この案件でmaterial-uiを初めて使いましたが、CSS苦手でも簡単にいい感じのUIができて感動しました。

今回は自分の復習のためでしたが、使う機会があれば参考にしてください。

シェア!

Threads
user
吉本茜
山口在住/二児の母/育休中
Loading...
記事一覧に戻る
Threads
0