You need to enable JavaScript to run this app. Next.js项目同一页面中如何实现多个react-table实例共存
优惠活动
大模型
产品
解决方案
定价
更多

Next.js项目同一页面中如何实现多个react-table实例共存

React-table同一页面渲染多个表格的实现方案

同一页面完全可以存在多个独立的react-table实例,每个实例的状态、配置、数据源完全隔离,不会互相影响。

方案1:封装可复用表格组件(更推荐)

把现有表格逻辑抽成独立组件,避免重复代码,后续维护也更方便:

第一步:封装通用Table组件

// 可以单独抽成文件,也可以直接写在当前页面文件里
import { useTable, useSortBy } from 'react-table'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCaretDown, faCaretUp, faArrowsAltV } from '@fortawesome/free-solid-svg-icons'
import styles from '你的样式文件路径'

const ReusableTable = ({ columns, data }) => {
  const tableInstance = useTable({
    columns,
    data
  }, useSortBy)

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = tableInstance

  return data.length > 0 ? (
    <div className={styles.tableSpace}>
      <table {...getTableProps()} className={styles.table}>
        <thead className={styles.thead}>
          {headerGroups.map((headerGroup) => (
            <tr {...headerGroup.getHeaderGroupProps()} className={styles.tr} key={headerGroup.id}>
              {headerGroup.headers.map((column) => (
                <th {...column.getHeaderProps(column.getSortByToggleProps())} className={styles.th} key={column.id}>
                  {column.render('Header')}
                  {column.Header !== 'Description' && (
                    <span>
                      {column.isSorted ? (
                        column.isSortedDesc ? 
                          <FontAwesomeIcon className={styles.faCaretDown} icon={faCaretDown} /> : 
                          <FontAwesomeIcon className={styles.faCaretUp} icon={faCaretUp} />
                      ) : (
                        <FontAwesomeIcon className={styles.faArrowsAltV} icon={faArrowsAltV} />
                      )}
                    </span>
                  )}
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()} className={styles.tbody}>
          {rows.map(row => {
            prepareRow(row)
            return (
              <tr {...row.getRowProps()} className={styles.tr} key={row.id}>
                {row.cells.map((cell) => {
                  return (
                    <td {...cell.getCellProps()} className={styles.td} key={cell.id}>
                      {cell.render('Cell')}
                    </td>
                  )
                })}
              </tr>
            )
          })}
        </tbody>
      </table>
    </div>
  ) : null
}

第二步:在页面中调用多个表格

// 你的页面文件中
// 假设你有第二套表格的配置和数据
const COLUMNS2 = [/* 第二个表格的列配置 */]
const tableData2 = [/* 第二个表格的数据源 */]

export default function YourPage() {
  return (
    <div>
      {/* 第一个表格 */}
      <ReusableTable columns={COLUMNS} data={tableData} />
      {/* 第二个表格 */}
      <ReusableTable columns={COLUMNS2} data={tableData2} />
      {/* 要更多表格继续加即可 */}
    </div>
  )
}

方案2:不封装组件,直接在当前文件声明多个实例

如果你不想抽组件,也可以直接声明多个实例,解构的时候对变量重命名避免冲突即可:

// 声明第一个表格实例
const tableInstance1 = useTable({
  columns: COLUMNS,
  data: tableData
}, useSortBy);
const {
  getTableProps: getTableProps1,
  getTableBodyProps: getTableBodyProps1,
  headerGroups: headerGroups1,
  rows: rows1,
  prepareRow: prepareRow1
} = tableInstance1;

// 声明第二个表格实例
const tableInstance2 = useTable({
  columns: COLUMNS2,
  data: tableData2
}, useSortBy);
const {
  getTableProps: getTableProps2,
  getTableBodyProps: getTableBodyProps2,
  headerGroups: headerGroups2,
  rows: rows2,
  prepareRow: prepareRow2
} = tableInstance2;

JSX部分分别使用对应实例的变量即可,第二个表格的JSX把所有属性替换为对应带2后缀的变量就行。

注意事项

你原代码中tbody的属性写的是{...getTableBodyProps},漏了调用括号,正确写法是{...getTableBodyProps()},否则会导致表格事件不生效。

内容的提问来源于stack exchange,提问作者Damien Lucchese

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 09:24:04