React中对useState存储的数组执行push操作后视图未重新渲染问题
问题根因
React 是通过判断状态的引用地址是否发生变化来决定是否触发组件重渲染的。你直接对 useState 返回的 totalNumbers 数组执行 push 操作,属于修改原数组本身,数组的内存引用地址没有发生变化,setTotalNumbers 传入的还是原来的数组引用,React 会认为状态没有更新,因此不会触发重渲染,界面颜色也就不会同步更新。
修复方案
只要给 setTotalNumbers 传入一个全新的数组即可触发正常更新,以下是3种常用的正确写法:
- 扩展运算符写法(最简洁常用)
const changeButtonColor = (event: any) => { const newId = Number(event.target.id) // 基于原数组生成全新数组传入 setTotalNumbers([...totalNumbers, newId]) }
- 数组concat方法写法
const changeButtonColor = (event: any) => { const newId = Number(event.target.id) // concat方法默认返回新数组,不会修改原数组 setTotalNumbers(totalNumbers.concat(newId)) }
- 先拷贝原数组再修改的写法(适合需要先对数组做复杂操作的场景)
const changeButtonColor = (event: any) => { const newId = Number(event.target.id) // 先浅拷贝一份原数组 const newTotalNumbers = [...totalNumbers] newTotalNumbers.push(newId) setTotalNumbers(newTotalNumbers) }
额外优化建议
- 移除不必要的
any类型注解,给状态指定明确的number[]类型,可以获得更好的 TypeScript 类型提示:const [totalNumbers, setTotalNumbers] = useState<number[]>([]) - 判断数字是否在选中数组中可以用
includes方法,语义更清晰易读:className={totalNumbers.includes(num) ? 'active' : 'desactive'}
内容的提问来源于stack exchange,提问作者Guilherme
相关产品推荐
相关产品推荐

