react-selectの基本的な使い方
はじめに
react-selectを使ってみたので基本的な使い方をまとめました。react-selectはReactで多機能なセレクトボックスを簡単に実装できるライブラリです。
実行環境:
- PHP:
8.2.x
- Laravel:
10.x
- React:
18.2.0
- react-select:
5.8.0
react-selectの導入
公式: React Select
インストール
npm i --save react-select
使い方
value
とlabel
キーを持ったオブジェクトリストを渡すだけです。例えば、ブログ記事の公開ステータスをセレクトボックスで選択したいとします。
import Select from 'react-select'
const statusOptions = [
{ value: 'public', label: '公開' },
{ value: 'private', label: '非公開' },
{ value: 'draft', label: '下書き' }
]
const MyComponent = () => (
<Select options={statusOptions} />
)
options
に渡す選択肢リストは、実際にはAPIレスポンスから受け取ったデータを使うことが多いと思います。例えば以下のようなusersデータはvalue
とlabel
キーは持っていないためreact-select
で使えるように変換が必要です。
// APIレスポンスから受け取るusersデータの形式を想定
const users = [
{ id: 1, name: 'ユーザー1', email: 'user1@example.com'},
{ id: 2, name: 'ユーザー2', email: 'user2@example.com'},
{ id: 3, name: 'ユーザー3', email: 'user3@example.com'},
];
const options = users.map(user => ({
value: user.id,
label: user.name
}));
既存のキーを残したい場合は、元のオブジェクトをスプレッド構文(...
)を使って新しいオブジェクトにコピーし、value
と label
を追加します。
const users = [
{ id: 1, name: 'ユーザー1', email: 'user1@example.com'},
{ id: 2, name: 'ユーザー2', email: 'user2@example.com'},
{ id: 3, name: 'ユーザー3', email: 'user3@example.com'},
];
const options = users.map(user => ({
...user, // 既存の全てのキーと値を保持
value: user.id, // valueキーを追加
label: user.name // labelキーを追加
}));
propsでカスタマイズ
選択肢の変更時イベント
onChange
<Select
options={options}
onChange={value => console.log(value)}
/>
選択されたオプションが変更されたときに実行されます。選択されたオプションを引数として受け取り、コンソールに出力して確認してみます。
{
id: 1,
name: "ユーザー1",
email: "user1@example.com",
value: 1,
label: "ユーザー1",
}
options
配列の中の選択されたオプションのuserオブジェクトを確認できました。
検索可能にする
isSearchable
<Select
options={options}
onChange={value => console.log(value)}
isSearchable={true}
/>
検索値が見つからない時のメッセージ変更
noOptionsMessage
<Select
options={options}
onChange={value => console.log(value)}
isSearchable={true}
noOptionsMessage={() => "見つかりません。"}
/>
選択肢解除可能にする
isClearable
<Select
options={options}
onChange={value => console.log(value?.name)}
isClearable={true}
/>
選択肢を解除するとonChange
はnull
を受け取ります。そのため、オブジェクトのプロパティにアクセスする場合はエラーにならないよう、Null 合体演算子 (??
)やオプション連鎖演算子 (?.
) を使うなどハンドリングが必要です。
選択肢の表示をカスタム
getOptionLabel
<Select
options={options}
onChange={value => console.log(value?.name)}
isSearchable={true}
isClearable={true}
getOptionLabel={option => option.label + ' : ' + option.email}
/>
デフォルトではlabel
キーの値が表示されますが、「名前 : email」のような形式で表示することもできます。検索時にemailもヒットするようになります。
初期値をセットする
value
にオブジェクトを指定する。
// inertiaを使った例
import { useForm } from '@inertiajs/react';
const { data, setData, post } = useForm({
user_id: 2, // 初期値を指定
});
...
<Select
value={options.find(obj => obj.id === data.user_id)} // 一致するものを探してセット
options={options}
onChange={value => setData('user_id', value?.id)}
isSearchable={true}
isClearable={true}
getOptionLabel={option => option.label + ' : ' + option.email}
/>
初期値はoptions
に渡した配列に含まれるオブジェクトで指定する必要があります。
options[0]
のように特定の要素を指定したり、例のようにfind
メソッドを使えばオブジェクトの特定のプロパティを検索して該当するオブジェクトを指定することもできます。
データ送信してみる
実際にSelect
コンポーネントを使ってデータを送信してみます。以下の例ではInertia.jsを使っています。
import Select from 'react-select'
import { useForm } from '@inertiajs/react';
const MyComponent = () => {
const users = [
{ id: 1, name: 'ユーザー1', email: 'user1@example.com'},
{ id: 2, name: 'ユーザー2', email: 'user2@example.com'},
{ id: 3, name: 'ユーザー3', email: 'user3@example.com'},
];
const options = users.map(user => ({
...user,
value: user.id,
label: user.name
}));
const { data, setData, post } = useForm({
user_id: 2,
});
function handleSubmit(e) {
e.preventDefault()
post('test');
}
return (
<>
<h2>テストフォーム</h2>
<form onSubmit={handleSubmit}>
<Select
value={options.find(obj => obj.id === data.user_id)}
options={options}
onChange={value => setData('user_id', value?.id)}
isClearable={true}
getOptionLabel={option => option.label + ' : ' + option.email}
/>
<button>送信</button>
</form>
</>
);
}
export default MyComponent
さいごに
他にもたくさんのpropsが用意されており、カスタマイズすれば色々なパターンのセレクトボックスが作れそうです。実際に使いながら便利な機能を見つけたら随時更新していきます。
参考ソース
react-selectの公式ドキュメント:
Inertia公式 useForm使い方など:
Null 合体演算子 (??
)、オプション連鎖演算子 (?.
) について: