developers blog

react-selectをreact-hook-formで使う

react-hook-formとreact-selectを組み合わせて使用する場合、Controllerコンポーネントを使用します。

シンプルなドロップダウンリスト

単純なセレクトボックスの場合は

  • render内にSelectコンポーネントを追加する
  • valueは、選択されたオプションのオブジェクトを設定する
  • onChangeでControllerのonChangeを呼びだす

となります。

参考:React Hook Form - UIライブラリを使用する

※上記のリンク先では、値の型が{label: string; value: string }と、Optionsと同じ型になっているため、そのままfieldの値を展開しているが、valueの値のみ必要なのでvalueonChangeを独自に指定しています。

index.tsx
1import { Controller, useForm } from "react-hook-form";
2import Select from "react-select";
3
4const Options = [
5  { value: 1, label: "りんご" },
6  { value: 2, label: "みかん" },
7  { value: 3, label: "バナナ" },
8];
9
10const Example = () => {
11  const { control } = useForm<{
12    id: number;
13  }>({
14    defaultValues: {
15      id: 2,
16    },
17  });
18
19  return (
20    <div>
21      <Controller
22        name="id"
23        control={control}
24        render={({ field }) => (
25          <Select
26            options={Options}
27            value={Options.find((x) => x.value === field.value)}
28            onChange={(newValue) => {
29              field.onChange(newValue?.value);
30            }}
31          />
32        )}
33      />
34    </div>
35  );
36};
37
38export default Example;

複数選択可能なドロップダウンリスト

複数選択を可能にするには

  • valueは、選択されたオプションの配列を設定する
  • onChangeにvalueの配列を設定する

とします。

index.tsx
1import { Controller, useForm } from "react-hook-form";
2import Select from "react-select";
3
4const Options = [
5  { value: 1, label: "りんご" },
6  { value: 2, label: "みかん" },
7  { value: 3, label: "バナナ" },
8];
9
10const Example = () => {
11  const { control } = useForm<{
12    id: number[];
13  }>({
14    defaultValues: {
15      id: [2],
16    },
17  });
18
19  return (
20    <div>
21      <Controller
22        name="id"
23        control={control}
24        render={({ field }) => (
25          <Select
26            options={Options}
27            value={Options.filter((x) => field.value.includes(x.value))}
28            onChange={(newValue) => {
29              field.onChange(newValue.map((x) => x.value));
30            }}
31            isMulti
32          />
33        )}
34      />
35    </div>
36  );
37};
38
39export default Example;

入力可能なドロップダウンリスト

入力可能なセレクトボックスを使用する場合は

  • import Creatable from "react-select/creatable"コンポーネントを使用する

とします。

index.tsx
1import { Controller, useForm } from "react-hook-form";
2import Creatable from "react-select/creatable";
3
4const Options = [
5  { value: "りんご", label: "りんご" },
6  { value: "みかん", label: "みかん" },
7  { value: "バナナ", label: "バナナ" },
8];
9
10const Example = () => {
11  const { control } = useForm<{
12    name: string;
13  }>({
14    defaultValues: {
15      name: "みかん",
16    },
17  });
18
19  return (
20    <div>
21      <Controller
22        name="name"
23        control={control}
24        render={({ field }) => (
25          <Creatable
26            options={Options}
27            value={Options.find((x) => x.value === field.value)}
28            onChange={(newValue) => {
29              field.onChange(newValue?.value);
30            }}
31          />
32        )}
33      />
34    </div>
35  );
36};
37
38export default Example;