1. React-Select とは
React-Select とは、セレクトボックスにオートコンプリート(入力による絞り込み)やマルチセレクト、async 機能がついた React 製コンポーネントです。
2. やること
デフォルトでは label
フィールドが表示対象、 value
フィールドが検索対象になります。
{ value: 'ocean', label: 'Ocean' },
{ value: 'blue', label: 'Blue'},
{ value: 'purple', label: 'Purple' },
{ value: 'red', label: 'Red' },
{ value: 'orange', label: 'Orange' },
...
このままだと以下のようなケースで問題があります。
- JSON に
label
とvalue
フィールドがない(別のフィールドを使用したい)- API のレスポンスなどを使用する場合など
- 表示をカスタマイズしたい
- 複数フィールドを組み合わせて表示
上記のようなケースもライブラリとしてカバーされていますが、公式ドキュメント がわかりづらかったのでどのようにすればいいかまとめました。
こちらが今回作成したデモです。
アカウント作成必要なくブラウザ上で動かせるので試して見てください。
3. 解説
1. 今回扱う JSON
社員マスタのようなものを想定してます。
{
EmployeeId: 1,
FirstName: "田中",
LastName: "健太郎",
DepartmentId: 2,
DepartmentName: "営業"
},{
EmployeeId: 2,
FirstName: "山田",
LastName: "五郎",
DepartmentId: 2,
DepartmentName: "営業"
},{
EmployeeId: 3,
FirstName: "マット",
LastName: "マックス",
DepartmentId: 2,
DepartmentName: "カスタマー"
},{
...
},{
EmployeeId: 6,
FirstName: "マット",
LastName: "マックス",
DepartmentId: 4,
DepartmentName: "開発"
}
フルネームと部署を表示・検索対象にすることを目標とします。
2. 表示をカスタマイズ
formatOptionLabel
に関数を渡します。
<Select
// omit
formatOptionLabel={formatOptionLabel}
/>
関数の引数に使用するフィールドを入れておけば OK です。
const formatOptionLabel = ({ FirstName, LastName, DepartmentName }) => (
<div style={{ display: "flex" }}>
<div>
{FirstName} {LastName}
</div>
<div style={{ marginLeft: "10px", color: "#999" }}>{DepartmentName}</div>
</div>
);
3. 検索対象の文字列
このままでは部署での検索ができないので、検索対象にしたいフィールドを getOptionLabel
で指定します。
今回はフルネームと部署が対象です。
<Select
// omit
getOptionLabel={option =>
option["FirstName"] + option["LastName"] + option["DepartmentName"]
}
/>
おわりに
似たようなもので React Autosuggest を使って見たことがありますが、私は React-Select の方が使いやすかったです。
ただ Issue の数がとんでもないので、ここら辺にも関わっていければなと思います。