React Bootstrap Table Next多复选框启用/禁用问题求助
React + Bootstrap Table Next 复选框禁用问题解决方案
核心问题分析
你直接修改row.isReadOnly = true不会触发组件重新渲染,因为React的UI更新依赖state/props的可变更动,直接修改原始row对象属于隐式修改,Bootstrap Table Next无法感知到这个变化,所以复选框的disabled状态不会更新。
解决方案
不用为每条记录单独维护state,用一个对象存储正在操作的行标识即可,既能避免重复点击,也不会因为几百条数据造成内存压力。
1. 组件state中维护操作状态
在组件的初始state里添加一个对象,用来记录哪些行处于操作中:
this.state = { isModalOpen: false, server: '', isInMaintenanceMode: false, loadingRows: {} // 键为row.name,值为布尔值,表示该行是否正在操作 };
2. 修改复选框的disabled逻辑
在formatter中,把disabled的判断改为原始的row.isReadOnly + 临时的操作状态:
formatter: (cell, row) => { const isDisabled = row.isReadOnly || this.state.loadingRows[row.name]; return ( <div className='text-right togglebox form-check form-check-inline'> <input type="checkbox" checked={ row.isInMaintenanceMode } disabled={ isDisabled } className="form-check-input" onChange={(e) => { // 先标记当前行为操作中,触发UI更新禁用复选框 this.setState(prev => ({ loadingRows: { ...prev.loadingRows, [row.name]: true } })); if (row.isInMaintenanceMode) { // 执行更新操作,完成后取消标记 this.props.update(row.name, { "/redirect" : false }) .finally(() => { this.setState(prev => ({ loadingRows: { ...prev.loadingRows, [row.name]: false } })); }); } else { // 打开模态框,此时复选框已经被禁用 this.setState({ isModalOpen: true, server: row.name, isInMaintenanceMode: !row.isInMaintenanceMode }); } }} /> </div> ); },
3. 处理模态框的确认/取消逻辑
模态框确认后执行update,完成后取消操作标记;如果用户取消,也要恢复复选框的可用状态:
// 模态框确认按钮点击事件 handleModalConfirm = () => { const { server } = this.state; this.props.update(server, { /* 维护模式开启的参数 */ }) .finally(() => { this.setState(prev => ({ isModalOpen: false, loadingRows: { ...prev.loadingRows, [server]: false } })); }); }; // 模态框取消按钮点击事件 handleModalCancel = () => { const { server } = this.state; this.setState(prev => ({ isModalOpen: false, loadingRows: { ...prev.loadingRows, [server]: false } })); };
关键注意点
- 永远不要直接修改原始的row对象,所有需要触发UI更新的状态变更,都要通过
setState或者父组件的props更新方法来完成。 loadingRows对象只会存储正在操作的行标识,即使有上千条数据,也只会占用少量内存,不用担心性能问题。
内容的提问来源于stack exchange,提问作者Mick
相关产品推荐
相关产品推荐

