React删除数组state数据后页面视图未更新问题解决
问题根因
视图不更新的核心原因是违反了React状态更新的不可变数据要求,删除逻辑存在两个明确错误:
const newPfps = pfps没有创建新数组,只是把原state数组的内存引用赋值给了新变量,newPfps和state里存储的pfps指向同一个数组splice是原地修改数组的方法,直接修改原state数组内容后,调用setPfps传入的还是原来的数组引用。React对state做浅比较时,发现数组引用地址没有变化,会判定状态没有更新,因此不会触发重渲染。控制台能打印到空数组,只是因为直接篡改了原数组的内容,React本身并没有感知到状态变更。
新增逻辑之所以正常,是因为用了展开运算符[...pfps, e.target.files[0]]创建了全新数组,引用地址发生了变化,React可以检测到更新。
另外补充:splice是同步执行的原生方法,前面加await没有任何实际作用,不需要把删除函数声明为async。
修复代码
修正删除逻辑
不要原地修改原数组,每次更新都生成全新的数组传入setState,推荐用filter直接生成过滤后的新数组,写法最简洁:
function removeFile(deleteIndex) { setPfps(pfps.filter((_, index) => index !== deleteIndex)) }
如果习惯先拷贝再操作的写法也可以,只要保证传入的是新数组引用即可:
function removeFile(deleteIndex) { // 先浅拷贝原数组生成新数组 const newPfps = [...pfps] newPfps.splice(deleteIndex, 1) setPfps(newPfps) }
对应的删除按钮点击事件不需要async包装,直接绑定即可:
<XIcon className='w-4 h-4 inline ml-3 mr-1' onClick={() => removeFile(index)} />
可选优化(规避闭包陷阱)
当前的新增、删除逻辑都存在闭包拿到旧state的风险,建议改成函数式更新写法,保证始终基于最新的state做计算,避免连续操作时出现状态异常:
// 新增文件逻辑优化 function handleSetPfps(e) { const file = e.target.files[0] if (!file) return setPfps(prevPfps => [...prevPfps, file]) } // 删除逻辑优化 function removeFile(deleteIndex) { setPfps(prevPfps => prevPfps.filter((_, index) => index !== deleteIndex)) }
内容的提问来源于stack exchange,提问作者Cyberguy Game
相关产品推荐
相关产品推荐

