React中通过Props传递数组给组件运行结果异常的问题咨询
问题原因
这不是React的Bug,问题出在你的sort_data函数中使用了会修改原数组的可变API,同时存在笔误逻辑问题。
核心问题1:误用数组可变方法
JavaScript的splice方法是可变方法,会直接修改调用它的原数组,而你传入sort_data的availableTimes、blockedTimes都是来自父组件的props,React要求props是只读不可修改的:
- 如果你直接修改props的原数组,当父组件重新渲染时,传入的props已经被你改得不符合预期
- React 18+的严格模式下,组件函数会执行两次,第一次执行时
splice已经把原数组的元素删空了,第二次执行拿到的是残缺的数组,自然输出不符合预期
核心问题2:逻辑笔误
你在处理i >= availableTimes.length的分支时,错误地对availableTimes调用了splice(j),正确的操作对象应该是blockedTimes,这个笔误也会导致合并结果错乱。
为什么深拷贝可以临时解决问题
你使用JSON.parse(JSON.stringify())深拷贝后,splice修改的是拷贝出来的新数组,不会影响原props中的数组,相当于规避了修改原props的问题,所以结果符合预期。但深拷贝属于不必要的性能开销,有更优的解决方案。
修复方案
不需要深拷贝,只需要把sort_data里的可变方法替换成不可变方法,同时修正笔误即可:
const sort_data = (availableTimes,blockedTimes) => { // WARN: availableTimes && blockedTimes are ordered! var ordered_times_array = [] for (let i = 0, j = 0 ; i < availableTimes.length || j < blockedTimes.length ;) { const a = availableTimes[i]; const b = blockedTimes[j]; if(j >= blockedTimes.length){ // 把splice换成slice,slice不会修改原数组 const array_left = availableTimes.slice(i) array_left.map((time) => ordered_times_array.push({available: true, time: time}) ) break; } if(i >= availableTimes.length){ // 修正笔误:操作对象换成blockedTimes,同时用slice代替splice const array_left = blockedTimes.slice(j) array_left.map((time) => ordered_times_array.push({available: false, time: time}) ) break; } else if(a < b){ ordered_times_array.push({available: true, time: a}) i++; } else{ ordered_times_array.push({available: false, time: b}) j++; } } return ordered_times_array; }
修改完成后直接调用sort_data(availableTimes,blockedTimes)即可得到正确结果。
内容的提问来源于stack exchange,提问作者Astro
相关产品推荐
相关产品推荐

