React点击表格表头排序时状态更新未触发重渲染问题
问题原因
你的判断完全正确,问题本质是React状态更新的不可变原则被破坏了:
Array.sort()是原地修改方法,它会直接在原数组上做排序操作,返回值和原数组是同一个内存引用- 你调用
data.sort()的时候,已经直接修改了state里存储的原数组,所以打印newdata能看到正确的排序结果,但传给setdata的还是和旧state完全相同的数组引用 - React对state更新做浅对比,发现新旧state引用地址一致,就会判定状态没有变化,跳过重渲染流程,同时依赖
data的useEffect也不会触发。
修复方法
修改排序逻辑,先创建原数组的副本,再在副本上执行排序操作,保证传入setdata的是全新引用的数组:
function handleHeaderClick(header) { // 用展开运算符先做一层浅拷贝,生成全新数组后再排序 const newdata = [...data].sort((a, b) => (a[header] > b[header] ? 1 : -1)); setdata(newdata); }
如果你的数组项是复杂嵌套对象,后续有修改对象深层属性的需求,再根据需要做深拷贝即可,当前排序场景浅拷贝就足够满足需求。
额外注意
React所有state更新都要遵循不可变原则:
- 不要直接修改state里存储的数组、对象本身
- 数组的修改操作(排序、过滤、新增、删除)都要基于原数组的副本执行,再把新副本传给setState
- 对象的修改同理,先拷贝原对象再修改属性,最后传入新对象
内容的提问来源于stack exchange,提问作者Collaxd
相关产品推荐
相关产品推荐

