React中await与useState结合代码的作用及重构问题咨询
我发现一段直接修改React状态的代码,此前了解到直接修改状态是严重的编码陋习,但尝试重构时功能出现异常。希望了解这段代码的逻辑,尤其是await与useState结合的作用,以便更好地完成重构。
代码如下:
const removeIndex = selectedCheckList.findIndex( (selectedVisit) => selectedVisit.visitId == selectedcheckItem.visitId, ) const removeKeyIndex = RowValue.findIndex( (selectedVisitRowIndex) => selectedVisitRowIndex == keyIndex, ) await selectedCheckList.splice(removeIndex, 1) await RowValue.splice(removeKeyIndex, 1) setSelectedCheckList(selectedCheckList) setRowValue(RowValue)
我尝试过在setState调用中内联检查、将setState移至末尾、用新局部变量保存状态更新后传入setState,但均未解决问题。现咨询:这些针对useState的await语句有什么作用,React是如何解析它们的?
解答
1. 这些await语句完全没有实际作用
Array.splice()是同步方法,它直接修改原数组并返回被删除的元素组成的数组,根本不是Promise对象。在它前面加await,JavaScript会把返回的数组自动包装成一个已resolved的Promise,然后立即继续执行后续代码——相当于完全没加await,代码还是同步执行的。React对这些await没有特殊解析逻辑,就是按照普通JavaScript的规则处理,所以这两行await纯粹是冗余代码,原作者可能误以为splice是异步操作,或者想当然加了await。
2. 原代码的核心问题:直接修改React状态
selectedCheckList和RowValue都是通过useState创建的状态变量,React要求状态必须是不可变的——你不能直接修改原状态对象/数组,必须创建新的引用传递给setState。原代码直接用splice修改原数组,然后把同一个数组引用传给setState,React会因为引用未发生变化,判断状态没有更新,从而不触发组件重渲染,或者导致状态与UI不同步,出现各种奇怪的bug。
3. 正确的重构方式
必须创建新的数组引用,而不是修改原数组,常用的方法有:
- 使用
filter过滤掉要删除的元素:
const newSelectedCheckList = selectedCheckList.filter( item => item.visitId !== selectedcheckItem.visitId ); const newRowValue = RowValue.filter(index => index !== keyIndex); setSelectedCheckList(newSelectedCheckList); setRowValue(newRowValue);
- 使用
slice结合展开运算符创建新数组:
const newSelectedCheckList = [ ...selectedCheckList.slice(0, removeIndex), ...selectedCheckList.slice(removeIndex + 1) ]; const newRowValue = [ ...RowValue.slice(0, removeKeyIndex), ...RowValue.slice(removeKeyIndex + 1) ]; setSelectedCheckList(newSelectedCheckList); setRowValue(newRowValue);
4. 重构后仍有问题的排查方向
如果按上面的方式重构后功能还是异常,可能的原因包括:
- 变量名拼写错误(比如原代码中的
selectedcheckItem大小写不一致) keyIndex或selectedcheckItem.visitId的值不符合预期,导致过滤/切片逻辑没生效- 组件其他部分依赖了原状态的引用,没有正确响应新状态的变化
内容的提问来源于stack exchange,提问作者rcm

