React求助:如何解决useEffect+reducer配合react-datepicker选时间出NaN?
解决React Reducer中
setTime分支的更新逻辑问题 看起来你现在的核心问题出在两个地方:一是没有把用户选中的时间传递给reducer,二是reducer里错误地尝试返回组件(这完全违背了reducer的纯函数职责)。咱们一步步来修复:
第一步:修正setTime的dispatch参数
首先,在Main组件的TimeClass调用中,你需要把用户选中的time传递给dispatch——因为DatePicker的onChange会把选中的时间对象作为参数传给setTime,所以要把这个值带进去,同时明确是更新start_time还是end_time(根据column判断):
{ _.times(2, (column)=><TimeClass key={column} time={start} endTime={end} column={column} setTime={(selectedTime) => reservationsDispatch({ type: 'setTime', rowIndex: row - 1, // 注意表格行号转数组索引(reservations是数组,从0开始) timeType: column === 0 ? 'start_time' : 'end_time', // 区分开始/结束时间 selectedTime: selectedTime // 传入用户选中的时间对象 })} /> )}
第二步:编写正确的setTime reducer逻辑
Reducer是纯函数,它的职责是接收旧state和action,返回新的state,绝对不能返回组件。你需要对原state做不可变更新,找到对应行,修改对应的时间字段,同时把时间转换成和后端一致的格式(避免NaN解析错误):
function reservationsReducer(state, action) { switch (action.type) { case 'replace': return action.data; case 'setTime': // 解构action中的参数 const { rowIndex, timeType, selectedTime } = action; // 不可变更新:复制数组→复制目标行→修改对应时间字段 return state.map((reservation, index) => { if (index === rowIndex) { // 把选中的Date对象转换成和初始数据一致的hh:mm:ss格式字符串 const formattedTime = moment(selectedTime).format("hh:mm:ss"); return { ...reservation, [timeType]: formattedTime // 动态更新start_time或end_time }; } return reservation; }); default: throw new Error(`Unsupported action type: ${action.type}`); } }
第三步:验证NaN问题的根源
之前出现NaN,大概率是因为:
- 没有传递
selectedTime给reducer,导致更新时时间值为undefined,moment解析失败 - Reducer没有返回正确的state结构,导致后续
startPicker/endPicker拿到错误值
修正后,reservations state会正确更新,start和end的moment解析能拿到合法字符串,就不会出现NaN了。
额外小提示
- 确保
row - 1的索引逻辑正确,和reservations数组的索引完全对应 - 始终保持时间格式前后一致:初始从后端拿到的是
hh:mm:ss字符串,更新时也要转换成相同格式,避免解析异常
内容的提问来源于stack exchange,提问作者Miska Rantala
相关产品推荐
相关产品推荐

