ReactSelect、とても便利ですね!初めて使った時は感動しました。
今回はReactSelectで用意されているAsyncSelectでデバウンスする方法を記しておきます。
デバウンスとは
連続して呼び出される同じ処理を制御すること。呼び出された間隔が特定の時間より短い場合、最初の呼び出しは無視されます。
例えば、「イベントAで処理Bを実行」というプログラムがあったとします。
普通だとイベントAが1秒間に3回起こったら、処理Bも3回実行されます。
ここで、処理Bに間隔1秒のデバウンスをするように設定すると、イベントAが1秒間に3回起こった場合、処理Bは1回のみ実行されます。
設定した間隔(今回は1秒)の範囲内で複数回処理Bが呼び出された場合、最後の呼び出しの1回分しか実行されません。
やり方
元々インストールされていることが多い軽量ライブラリ、lodash(_)を使用。
TypeScriptを使用している場合は、型ファイルを追加インストールする必要があるかもしれません。
0.5秒(500ミリ秒)のデバウンスを適用しています。
import React from 'react'
import _ from 'lodash'
import AsyncSelect from 'react-select/async'
import { optionList } from '../data'
export const Form: React.FC = () => {
const [selectedValue, setSelectedValue] = useState<string>()
// デバウンス処理
const debouncedLoadOptions = _.debounce(
(
inputValue: string,
callback: (options: { label: string; value: string }[]) => void
) => {
callback(filterOptions(inputValue))
},
500 // 500ミリ秒
)
const filterOptions = (inputValue: string) => {
return optionList.filter((option) => option.label.includes(inputValue))
}
return (
<div>
<p>inputValue: {selectedValue}</p>
<AsyncSelect
cacheOptions
loadOptions={debouncedLoadOptions}
defaultOptions
onChange={(option) => setSelectedValue(option?.value)}
/>
</div>
)
}

Reactでデバウンスさせたい!となった時は、React hooksのuseDebounceも検討に入れるといいと思います。今回は使いにくかったのでlodashにしましたが^^;