React类组件更新状态时如何避免无限循环(非Hook方案)
解决React类组件复选框无限循环与状态更新问题
首先,你遇到的无限循环大概率是因为复选框的事件绑定写法错误,比如直接在onChange里执行函数(而非传递回调函数),导致组件每次渲染都会触发handleCheckClick,进而调用setState引发重复渲染循环。先修正事件绑定,再实现正确的状态更新逻辑:
1. 正确的复选框事件绑定
确保你的复选框是这样写的,不要直接调用函数,而是传递一个回调:
<input type="checkbox" onChange={() => this.handleCheckClick('目标名称', 10)} checked={this.state.checked.includes('目标名称')} />
如果直接写onChange={this.handleCheckClick('目标名称', 10)},组件渲染时会立刻执行这个函数,触发setState后重新渲染,再次执行函数,形成无限循环。
2. 正确的handleCheckClick实现
使用setState的函数式更新(依赖prevState),判断当前名称是否已在选中数组中,分别处理添加/移除逻辑,同时同步更新重量总和:
handleCheckClick = (name, weight) => { this.setState(prevState => { // 判断当前name是否已被选中 const isChecked = prevState.checked.includes(name); let newChecked; let newCheckedWeight; if (isChecked) { // 取消勾选:移除name,减去对应weight newChecked = prevState.checked.filter(item => item !== name); newCheckedWeight = prevState.checkedWeight - weight; } else { // 勾选:添加name,加上对应weight newChecked = [...prevState.checked, name]; newCheckedWeight = prevState.checkedWeight + weight; } return { checked: newChecked, checkedWeight: newCheckedWeight }; }); };
为什么这个写法能避免问题?
- 使用
prevState确保拿到的是最新的状态值,避免直接访问this.state导致的状态不一致问题; - 一次
setState同时更新两个状态,减少不必要的渲染; - 通过
includes判断状态,避免重复添加或错误移除; - 配合复选框的
checked属性绑定,确保复选框的状态和组件state同步,不会出现异常触发。
3. 你的旧代码问题分析
- 第一个写法:直接使用
this.state.checked和this.state.checkedWeight,状态更新是异步的,可能拿到的不是最新值;而且两次调用setState会触发两次渲染,同时没有判断是否已选中,会重复添加相同name; - 第二个写法:同样没有判断是否已选中,而且只更新了
checked数组,没处理checkedWeight,同时如果事件绑定错误,依然会引发无限循环。
内容的提问来源于stack exchange,提问作者Melanie Sigrid
相关产品推荐
相关产品推荐

