You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何同时对多个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:15:35