React Table 6实现打开新行子组件弹窗时自动关闭旧弹窗并解决数据错乱问题
React Table 6实现打开新行子组件弹窗时自动关闭旧弹窗并解决数据错乱问题
看起来你遇到了React Table子组件弹窗数据错乱的典型问题,这是因为所有行的弹窗共享了同一个状态,而且没有和具体的行数据绑定,我来帮你一步步解决:
问题根源
- 所有子组件的Modal共用同一个
isPopUpOpen状态,没有关联到具体的行,导致切换行时旧弹窗可能没关闭,新弹窗打开后数据还是旧的 - 弹窗内容直接依赖
row.original,但这个row参数是SubComponent渲染时的行引用,切换行后没有更新到新行的数据
解决方案
我们需要给弹窗绑定具体的行数据状态,同时优化弹窗的打开/关闭逻辑:
1. 更新组件初始状态
首先在你的组件state里新增两个关键状态,专门管理弹窗的行数据:
this.state = { // 保留你原有状态(schemaData、columns、page等) isPopUpOpen: false, currentRowData: null, // 存储当前打开弹窗的行数据 };
2. 修改弹窗打开/关闭方法
让openPopUp接收当前行数据,更新状态后再打开弹窗;closePopUp重置行数据,确保下次打开是干净的状态:
openPopUp = (row) => { // 直接覆盖旧数据并打开弹窗,无需额外判断,React会自动更新状态 this.setState({ currentRowData: row.original, isPopUpOpen: true }); }; closePopUp = () => { this.setState({ isPopUpOpen: false, currentRowData: null }); };
3. 调整SubComponent和Modal的渲染逻辑
把弹窗内容的数据源从row.original换成this.state.currentRowData,同时修改打开按钮的点击事件,传递当前行:
<ReactTable className="react-table" data={this.state.schemaData} columns={this.state.columns} showPagination={true} showPaginationBottom={true} defaultPageSize={5} page={this.state.page} pageSizeOptions={[3, 5, 7, 10, 15]} // 分页切换时自动关闭弹窗,避免残留旧内容 onPageChange={page => this.setState({ page: page, isPopUpOpen: false, currentRowData: null })} collapseOnDataChange={true} SubComponent={(row) => { return ( <div> {/* 点击时把当前行数据传递给openPopUp */} <button onClick={() => this.openPopUp(row)}> View Record Data </button> <Modal style={{ overlay: { backgroundColor: 'transparent', } }} className="modalTest" isOpen={this.state.isPopUpOpen} onRequestClose={this.closePopUp} contentLabel="Example Modal" > <button className="close" onClick={this.closePopUp} > Close </button> <div> {/* 先判断currentRowData是否存在,避免空值报错 */} {this.state.currentRowData && Object.keys(this.state.currentRowData).map((key) => { return ( <table className="table-Sub" key={key}> {/* 加key避免React列表渲染警告 */} <tr className="tr-Sub"> <th className="th-sub"> <span className="key">{key}</span> </th> <td className="td-sub"> <span className="keyData"> {key !== "is_enabled" ? ( this.state.currentRowData[key] !== null ? this.state.currentRowData[key] : "NULL" ) : ( this.state.currentRowData[key] === false ? 0 : 1 )} </span> </td> </tr> </table> ) })} </div> </Modal> </div> ) }} />
4. 额外优化点
- 给循环渲染的
table加上key={key},符合React列表渲染的规范,避免控制台警告 - 在
onPageChange里自动关闭弹窗,切换页面时不会残留旧的弹窗内容,提升用户体验
为什么这样修改能解决问题?
- 用
currentRowData状态统一管理弹窗要展示的数据,切断了和SubComponent的row参数的直接依赖,每次打开弹窗都会更新到最新的行数据 - 打开弹窗时自动覆盖旧的行数据,确保弹窗内容始终是当前点击行的信息
- 分页切换时自动关闭弹窗,避免用户切换页面后还看到旧的弹窗内容
内容来源于stack exchange
相关产品推荐
相关产品推荐

