React Hooks遍历数据时如何动态设置checkbox的defaultChecked属性
问题原因
- 无限重渲染触发原因:你在
defaultChecked属性中直接执行了setStatusMode(el.enabled, k),React组件渲染阶段同步调用状态更新函数会触发组件重渲染,进而进入「渲染→更新状态→再渲染」的无限循环,触发React的渲染次数限制报错。 - 状态设计错误:你定义了单个
statusMode状态存储所有行的开关值,不符合业务逻辑——每行的启用/禁用状态是独立的,完全可以直接复用已经请求到的data数组中每条数据自带的enabled字段,不需要额外定义冗余状态。
正确实现方案
1. 移除冗余状态,调整开关切换逻辑
删掉没用的statusMode状态,切换开关时先更新本地data数组的状态保证界面即时响应,再调用后端接口同步数据:
// 只保留data状态即可,无需额外statusMode const [data, setData] = useState([]); const fetchData = async () => { let json = await getData(); setData(json); } const updateToggle = async (rowID, currentEnabled) => { // 先更新本地状态,界面立刻响应 const newData = data.map(item => { if(item.id === rowID) { return {...item, enabled: !currentEnabled} } return item }) setData(newData) // 再调用后端接口同步状态 const updateData = {'id': rowID} if (currentEnabled) { await disable(updateData); } else { await enable(updateData); } };
2. 修改渲染逻辑,使用受控Checkbox
不要用defaultChecked,改用受控组件的checked属性直接绑定每条数据的enabled值,渲染阶段不要调用任何状态更新函数:
{data.map((el, k) => { return ( <div key={k}> <div className="checkbox"> <label className="switch"> <input type="checkbox" checked={el.enabled} onClick={() => updateToggle(el.id, el.enabled)} /> </label> </div> </div> ); })}
补充说明
- React中HTML的
class属性要写为className,否则会有属性不生效的问题 - 使用受控组件绑定
checked而不是defaultChecked的原因是:defaultChecked只在组件第一次渲染时生效,后续数据更新不会同步改变开关状态,受控组件可以保证状态和视图始终一致 - 先更本地状态再调用接口的方案可以避免接口请求耗时导致的界面卡顿感,如果需要严格保证接口请求成功再更新界面,可以把本地状态更新的逻辑放到接口请求成功的回调里。
内容的提问来源于stack exchange,提问作者uberrebu
相关产品推荐
相关产品推荐

