React中受数组状态控制的按钮组件点击未正常重渲染如何解决?
问题核心原因
你的代码违反了React状态更新的不可变性原则,直接修改了原状态数组的引用,导致状态更新识别异常:
- 点击未激活按钮不触发重渲染:代码中
let stockOperators = activeOperators直接对原状态数组做引用赋值,没有生成新数组。else分支调用push是直接修改原数组的内容,再调用setActiveOperators传入的还是原数组的引用,React做状态浅比较时认为数组没有变化,因此跳过重渲染。但此时原数组的内容已经被修改,只是没有触发视图更新。 - 点击已激活按钮时连带之前的未激活按钮一起更新:当你点击已激活的按钮时,走filter分支,filter方法会返回一个全新的数组,引用和原数组不同,React识别到状态变化触发重渲染。此时渲染用的状态数组已经包含了之前几次push操作偷偷修改的内容,所以之前点击过的未激活按钮都会在这次渲染中同步更新状态。
修复方案
只需要修改handlingOperators方法,操作状态前先拷贝原数组,保证每次状态更新都是传入新的数组引用即可:
const handlingOperators = (operatorInput) => { // 先拷贝原数组,不直接修改原状态 let stockOperators = [...activeOperators]; if ( stockOperators.length > 0 && stockOperators.some((operator) => { return operator === operatorInput; }) ) { stockOperators = stockOperators.filter((operator) => { return operator !== operatorInput; }); setActiveOperators(stockOperators); } else { stockOperators.push(operatorInput); setActiveOperators(stockOperators); } };
补充说明
React的所有状态更新都要求遵循不可变性原则,对于引用类型(数组、对象)不能直接修改原内容,必须返回全新的引用,否则React会因为浅比较结果一致而跳过更新,出现状态和视图不同步的异常。你之前用四个布尔值可以正常运行,就是因为布尔值是基础类型,每次更新都是值的变化,React可以正常识别。
内容的提问来源于stack exchange,提问作者FlowRan
相关产品推荐
相关产品推荐

