概要
超初心者エンジニアが0:00~24:00の間で開始時刻<終了時刻になるような選択式メニューの作り方を考えました。
<input type="time">
などは時計マークから詳細設定が可能になってしまうので、手動で選択肢を設定しようと思った結果、このような方法にしました。
前提
ReactのuseState,useEffectを用いて管理します。
また、React UI ライブラリAntdesignのSelectメニューを使用しました。
Reactコンポーネント
returnに入る内容です。私はそれぞれをFormItemとして使いました。
// 開始時刻の選択
<Select
onChange={handleStartChange}
options={startTimeOption}
/>
// 終了時刻の選択
<Select
onChange={handleEndChange}
options={endTimeOption}
/>
使用するState
AntdesignのSelectで表示する選択肢は{ value: number; label: string; }[]
形式でないといけないらしいです。
// 開始時刻の選択肢は0~startTimeMax
const [startTimeMax, setStartTimeMax] = useState<number>(23)
const [startTimeOption, setStartTimeOption] = useState<{ value: number; label: string; }[]>([])
// 終了時刻の選択肢はendTimeMin~24
const [endTimeMin, setEndTimeMin] = useState<number>(1)
const [endTimeOption, setEndTimeOption] = useState<{ value: number; label: string; }[]>([])
片方選択時にもう片方の選択肢の範囲を変更
絶対に範囲が被らないようにします。
const handleStartChange = (value: number) => { setEndTimeMin(value + 1) };
const handleEndChange = (value: number) => { setStartTimeMax(value - 1) };
範囲の変更に伴い選択肢を自動作成
上で設定した値の変更があるたびにuseEffectで選択肢を生成しなおします。
// 開始時間の選択肢
useEffect(() => {
const options: { value: number; label: string }[] = [];
for (let i = 0; i < startTimeMax + 1; i++) {
options.push({ value: i, label: `${i}:00` });
};
setStartTimeOption(options);
}, [startTimeMax]);
// 終了時間の選択肢
useEffect(() => {
const options: { value: number; label: string }[] = [];
for (let i = endTimeMin; i < 25; i++) {
options.push({ value: i, label: `${i}:00`) });
};
setEndTimeOption(options);
}, [endTimeMin]);
最後に
初めてのReact、初めてのアプリ開発で手探りながらも自分の分かる要素を組み合わせてコードを書いてみました。
Formの中に入れ込む場合は提出後にstartTimeMaxとendTimeMinを初期値にリセットする処理を忘れずに。
もっと綺麗な解決法があるかもしれませんが、少しでも自分と同じ初心者エンジニアの方の助けになれば幸いです。