React Select联动问题:修改第一个选择器后第二个值不更新
问题描述
我有一个包含两个同类子组件的父组件,当选择第一个React Select的时间选项时,希望按规则设置第二个选择器的值:若第一个时间大于第二个选择器的值,或第二个选择器无值,则将其设为第一个时间加1小时。
目前的问题是,虽然已调用setEndTime,但第二个选择器的实际值并未更新,仅手动修改时才会显示对应值,请问我遗漏了什么?
原代码
子组件MyTimePicker
const MyTimePicker = (props) => { const [currentValue, setCurrentValue] = useState(null); const changeSelectedTime = (value) => { props.onTimeChanged(value); setCurrentValue(value.value); } console.log('current day: ' + props.CurrentDay) let timeArray = timeSlotArray.map(x => {return {value: x, label: x.getHours() + ':' + (x.getMinutes()<10 ? '0':'') + x.getMinutes()}}); return ( <div> <Select className={classes.selectBox} options={timeArray} onChange={changeSelectedTime} value={timeArray.filter((o)=>{return ( currentValue ? currentValue.getTime() === o.value.getTime() : false)})}></Select> </div> ); } export default MyTimePicker;
父组件AddSchedule
import MyTimePicker from '../UI/MyTimePicker'; const AddSchedule = (props) => { const [startTime, setStartTime] = useState(props.ClickedStartTime); const [endTime, setEndTime] = useState(props.ClickedStartTime); const onStartTimeChange = (newTime) => { setStartTime(newTime.value); if(newTime.value >= endTime || !endTime) { let newned = new Date(newTime.value.getTime()); setEndTime(newned.setHours(newned.getHours() + 1)); } } const onEndTimeChange = (newTime) => { setEndTime(newTime.value); } return ( <Modal> <MyTimePicker me='start' CurrentDay={Date()} onTimeChanged={onStartTimeChange} value={startTime}></MyTimePicker> <MyTimePicker me='end' CurrentDay={Date()} onTimeChanged={onEndTimeChange} value={endTime}></MyTimePicker> </Modal> ) } export default AddSchedule;
问题根源
- 子组件内部状态未同步父组件props:子组件维护了独立的
currentValue状态,但没有监听父组件传入的value变化来更新这个状态,导致父组件更新endTime时,子组件无法感知并同步显示。 setEndTime参数类型错误:newned.setHours()返回的是时间戳(数字类型),但父组件中endTime初始值是Date类型,类型不匹配导致后续比较和子组件处理逻辑失效。- react-select的value格式错误:子组件中
Select的value使用filter返回数组,但react-select期望的是单个选项对象,而非数组,这会导致选中状态渲染异常。
修复方案
修改子组件MyTimePicker
移除内部独立状态,直接依赖父组件传入的value props,简化选中值匹配逻辑:
const MyTimePicker = (props) => { const changeSelectedTime = (value) => { props.onTimeChanged(value); } const timeArray = timeSlotArray.map(x => ({ value: x, label: `${x.getHours()}:${x.getMinutes() < 10 ? '0' : ''}${x.getMinutes()}` })); // 根据父组件传入的value匹配对应选项 const selectedOption = timeArray.find(o => props.value && o.value.getTime() === props.value.getTime() ); return ( <div> <Select className={classes.selectBox} options={timeArray} onChange={changeSelectedTime} value={selectedOption} /> </div> ); } export default MyTimePicker;
修改父组件AddSchedule
修正setEndTime的参数类型,确保传递的是Date对象而非时间戳:
import MyTimePicker from '../UI/MyTimePicker'; const AddSchedule = (props) => { const [startTime, setStartTime] = useState(props.ClickedStartTime); const [endTime, setEndTime] = useState(props.ClickedStartTime); const onStartTimeChange = (newTime) => { const newStartTime = newTime.value; setStartTime(newStartTime); if (!endTime || newStartTime >= endTime) { const newEndTime = new Date(newStartTime.getTime()); newEndTime.setHours(newEndTime.getHours() + 1); // 传递Date对象而非时间戳 setEndTime(newEndTime); } } const onEndTimeChange = (newTime) => { setEndTime(newTime.value); } return ( <Modal> <MyTimePicker me='start' CurrentDay={new Date()} onTimeChanged={onStartTimeChange} value={startTime} /> <MyTimePicker me='end' CurrentDay={new Date()} onTimeChanged={onEndTimeChange} value={endTime} /> </Modal> ) } export default AddSchedule;
内容的提问来源于stack exchange,提问作者Dani
相关产品推荐
相关产品推荐

