如何同时对多个React Table实例进行排序?
实现两个React Table实例同步排序
要让两个列结构相同、数据不同的React Table同步排序,核心是把排序状态提到父组件共享,让两个表格共用同一套排序规则——当任意一个表格触发排序时,同步更新另一个表格的排序状态。具体实现步骤如下:
1. 父组件维护共享排序状态
在App组件中,用useState保存React Table所需的sortBy状态(格式为包含id(列名)和desc(是否倒序)的对象数组),同时定义更新状态的方法。
2. 封装自定义受控Table组件
把原本的Table组件改为受控组件,接收父组件传递的sortBy和onSortChange属性,在useTable钩子中传入sortBy,并通过useSortBy的排序回调触发onSortChange,将最新的排序状态同步到父组件。
3. 两个表格共享状态与回调
让左右两个表格实例都使用这个自定义组件,传入各自的数据,同时共享父组件的sortBy和onSortChange,这样就能实现一方排序时另一方同步跟进。
完整代码示例
import { useState } from 'react'; import { useTable, useSortBy } from 'react-table'; // 自定义受控Table组件 function SyncTable({ columns, data, sortBy, onSortChange }) { const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow, } = useTable( { columns, data, sortBy, // 使用父组件传入的排序状态 onSortChange: newSortBy => { // 触发父组件更新排序状态 onSortChange(newSortBy); }, }, useSortBy ); return ( <table {...getTableProps()}> <thead> {headerGroups.map(headerGroup => ( <tr {...headerGroup.getHeaderGroupProps()}> {headerGroup.headers.map(column => ( <th {...column.getHeaderProps(column.getSortByToggleProps())}> {column.render('Header')} {/* 显示排序方向标识 */} <span> {column.isSorted ? (column.isSortedDesc ? ' ↓' : ' ↑') : ''} </span> </th> ))} </tr> ))} </thead> <tbody {...getTableBodyProps()}> {rows.map(row => { prepareRow(row); return ( <tr {...row.getRowProps()}> {row.cells.map(cell => { return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>; })} </tr> ); })} </tbody> </table> ); } function App() { // 初始化共享排序状态,为空数组表示无默认排序 const [sortBy, setSortBy] = useState([]); // 示例列配置,替换成你的实际列定义 const columns = [ { Header: '名称', accessor: 'name' }, { Header: '总数', accessor: 'total' }, // 其他列... ]; const data1 = [/* 左表数据 */]; const data2 = [/* 右表数据 */]; return ( <div style={{ display: 'flex', gap: '20px' }}> <div className="left-table"> <SyncTable columns={columns} data={data1} sortBy={sortBy} onSortChange={setSortBy} /> </div> <div className="right-table"> <SyncTable columns={columns} data={data2} sortBy={sortBy} onSortChange={setSortBy} /> </div> </div> ); }
关于你提到的按钮/复选框方案
如果需要手动触发排序(比如通过按钮选择排序列),也可以基于这个共享状态实现:在父组件中添加按钮,点击时直接调用setSortBy设置对应的排序规则(例如setSortBy([{ id: 'total', desc: false }])),两个表格会自动同步排序状态。
内容的提问来源于stack exchange,提问作者C.Fletcher
相关产品推荐
相关产品推荐

