created: 2023-06-23T06:05:21.234Z

react-select で option を選択しても検索文字列をキープするように

react-select のデフォルトは、選択肢を選んだときに検索文字列をリセットしてしまう。

この動作は択一のセレクトボックスだと自然なのだが、isMulti をつかって複数項目選択できるコントローラの場合だと、1つを選択したあとに他の選択肢も同じ検索をしてから選ぶことになる。その場合は不便になるのでそこをケアする実装が必要になる。

v1の時はこの isMulti のときに望ましい動作をさせるために onSelectResetsInput={false} というオプションが用意されていたのだが deprecate になっているようだ。(closeOnSelect は後継のオプションである closeMenuOnSelect が実装されている)

今だとこういった実装をすると期待通りに動作した。

export const SelectBox: React.FC<Props> = ({
  options,
  initialValues,
}) => {
  const [filterInput, setFilterInput] = useState("");
  return (
    <Select
      defaultValue={defaultValue}
      options={options}
      // 
      inputValue={filterInput}
      closeMenuOnSelect={false}
      onInputChange={(inputValue: string, actionMeta: InputActionMeta) => {
        const { action, prevInputValue } = actionMeta;
        if (action === "set-value") {
          setFilterInput(prevInputValue);
        } else {
          setFilterInput(inputValue);
        }
      }}
    />
  );
};

onInputChange は option が選択されたときの他にも、検索文字列が更新された場合にも呼ばれるので、そこに実装をしてやればよい。どのイベントによってキックされているかは第二引数の actionMeta によって判別できる。

optionが選択されたときのイベントは action="set-value" なのでこのイベントのときにリセット前の prevInputValue 検索文字列 inputValue に設定してやればよい。

知ってるつもり 無知の科学 (ハヤカワ文庫NF)
[ad] 知ってるつもり 無知の科学 (ハヤカワ文庫NF)
スティーブン スローマン, フィリップ ファーンバック (Kindle版)