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
相关产品推荐
相关产品推荐

