如何解决React-Table类组件中状态更新导致展开行自动收起的问题
类组件React Table展开行状态保持解决方案
问题根因
你遇到的展开行自动收起、SubComponent渲染异常是以下几个原因导致的:
- 未给表格指定稳定的行唯一标识,状态更新触发重渲染时,表格无法匹配原有行,直接重置展开状态
- 使用
viewIndex/index作为展开状态的存储key,索引会随分页、排序、数据变更发生变化,导致展开状态错位 currentExpandedKeys为外部临时变量,组件重渲染时数据丢失,导致SubComponent无法拿到对应列key渲染嵌套表格- 手动控制expanded状态的同时调用了内部默认的
handleOriginal方法,两者逻辑冲突
修复代码
第一步:调整组件state定义
// 原有state基础上新增两个状态字段 state = { // 其他已有状态:比如checkbox选中状态等 expanded: {}, // 存储行展开状态,key为行数据唯一id currentExpandedKeys: {} // 存储每行展开对应的列ID,用于SubComponent渲染 }
第二步:修改ReactTable组件配置
return ( <ReactTable data={data} columns={columns} className='-striped -highlight' minRows={0} defaultPageSize={PAGE_SIZE} showPagination={data && data.length > PAGE_SIZE} // 核心配置1:指定行数据的唯一标识字段,确保重渲染时行匹配正确 keyField="id" // 核心配置2:开启展开状态冻结,数据更新时不自动重置已展开行 freezeWhenExpanded={true} expanded={this.state.expanded} SubComponent={(row) => { // 从state中取当前行对应的展开列ID const currentExpandedKey = this.state.currentExpandedKeys[row.original.id]; if (!currentExpandedKey) return null; return ( <div className='react-nested-table-inner'> <h4 className='title'> {keyMaps[currentExpandedKey] || currentExpandedKey} </h4> {this.renderByData( row.original[currentExpandedKey], keyMaps, onCellDisplay )} </div> ); }} getTdProps={(state, rowInfo, column, instance) => { return { onClick: (e, handleOriginal) => { if (column.expander && rowInfo) { const rowUniqueId = rowInfo.original.id; const newExpanded = { ...this.state.expanded }; const newExpandedKeys = { ...this.state.currentExpandedKeys }; // 切换展开状态 newExpanded[rowUniqueId] = !newExpanded[rowUniqueId]; if (newExpanded[rowUniqueId]) { // 展开时存储对应列ID newExpandedKeys[rowUniqueId] = column.id; } else { // 收起时删除冗余存储 delete newExpandedKeys[rowUniqueId]; } this.setState({ expanded: newExpanded, currentExpandedKeys: newExpandedKeys }); } // 不要调用默认的handleOriginal,避免和手动控制的状态冲突 } }; }} /> );
关键修改说明
- 如果你的行数据没有
id字段,可以替换成其他稳定的唯一标识,比如keyField="code",或者自行拼接不会重复的字段组合 freezeWhenExpanded是React Table v6版本的专属配置,专门用于解决数据更新时展开行自动收起的问题- 所有状态都存在组件state中,重渲染时不会丢失,SubComponent可以正常渲染嵌套表格
内容的提问来源于stack exchange,提问作者Ajay Shivanagol
相关产品推荐
相关产品推荐

