React.js函数式组件中state未更新导致复选框无响应问题
问题根因
你遇到的问题是违反了React的不可变数据原则导致的:
- 数组属于引用类型,代码中
let localChecked = checked仅复制了原state数组的内存引用,两者指向完全相同的数组对象 - 你直接修改这个引用对应的值,本质是直接修改原state,没有生成新的数组对象
- React更新state时会做浅比较,发现传入的数组引用和之前完全一致,就会判定state没有变化,跳过重渲染流程,也不会更新开发者工具中的state值
- 你在setTimeout中打印的内容是闭包捕获到的被你手动修改过的原数组值,属于假象,不代表React的state实际完成了更新
解决方案
只需要在修改state前创建全新的数组副本即可,推荐以下几种写法:
写法1:扩展运算符创建副本
const handleChangeChild = (event) => { const index = parseInt(event.target.id.slice(0, 1)); // 用扩展运算符生成全新数组副本 const localChecked = [...checked]; localChecked[index] = !localChecked[index]; setChecked(localChecked); };
写法2:函数式更新(更稳妥,避免闭包陷阱)
如果你的更新逻辑依赖之前的state值,推荐使用setState的函数式写法,保证能拿到最新的state:
const handleChangeChild = (event) => { const index = parseInt(event.target.id.slice(0, 1)); setChecked(prevState => { const newChecked = [...prevState]; newChecked[index] = !newChecked[index]; return newChecked; }); };
写法3:map方法生成新数组(函数式风格)
const handleChangeChild = (event) => { const index = parseInt(event.target.id.slice(0, 1)); setChecked(prev => prev.map((val, i) => i === index ? !val : val)); };
内容的提问来源于stack exchange,提问作者ariel-walley
相关产品推荐
相关产品推荐

