React列表状态设置两种方法差异咨询:为何unshift方式重复添加?
两种React列表状态更新方法的差异分析
第一种方法(使用unshift修改原数组)
示例代码:
setEatenFoodList(prevList => { prevList.unshift(addedFood); return prevList; });
问题根源:
unshift是直接修改原数组的方法,执行后原prevList的内容会被改变,且返回的还是同一个数组引用。- React要求状态是不可变的,修改原状态会打破这个原则。在开发环境的严格模式下,React会重复调用状态更新函数检测副作用,第一次调用已把元素加到原数组,第二次调用时
prevList已是修改后的数组,再次unshift就会导致元素被添加两次。 - 若返回和之前相同的数组引用,React可能无法正确识别状态变化,导致组件不触发重新渲染或渲染错误内容。
第二种方法(使用扩展运算符创建新数组)
示例代码:
setEatenFoodList(prevList => [addedFood, ...prevList]);
为什么符合预期:
- 扩展运算符
...会复制原数组的所有元素,创建一个全新的数组,把addedFood放在新数组开头。整个过程完全不修改原prevList,遵守了React状态不可变的原则。 - 每次状态更新都返回新的数组引用,React能准确识别状态变化,触发正确渲染。即使在严格模式下被重复调用,每次都是基于原始的
prevList创建新数组,不会出现重复添加的问题。
核心差异总结
- 对原数组的操作:第一种修改原数组(违反不可变性),第二种保持原数组不变,仅创建新数组。
- 状态更新的稳定性:第一种在严格模式或重复触发更新时会出现重复添加等异常,第二种不会。
- React的状态识别:第一种返回相同引用可能导致状态不更新,第二种返回新引用确保状态变更被正确捕获。
内容的提问来源于stack exchange,提问作者oussamaZAAM
相关产品推荐
相关产品推荐

