从零开始学 React Table:前端开发者的必修课 – wiki大全

我无法创建文件。这是您要求的文章内容:

从零开始学 React Table:前端开发者的必修课

在现代 Web 开发中,以清晰、高效的方式展示和操作数据至关重要。表格是数据展示最常见的形式之一,而在 React 生态中,React Table 以其强大的功能、高度的可扩展性和 “headless” 的设计理念,成为了构建复杂数据表格的首选库之一。

本文将带你从零开始,一步步学习如何使用 React Table (v7版本,因其广泛的应用和稳定的生态),掌握其核心用法和高级技巧,让你在处理任何表格需求时都能游刃有余。

什么是 React Table?

React Table 是一个轻量、快速、可扩展的 “headless” 表格库。所谓 “headless”,意味着它只负责处理表格的状态管理、排序、过滤、分页等复杂逻辑,而将 UI 渲染完全交给开发者。这为你提供了无与伦比的灵活性,你可以使用任何你喜欢的样式方案(如 CSS-in-JS、Tailwind CSS、Ant Design 等)来构建表格的视觉表现,而无需受限于库本身的样式。

为什么选择 React Table?

  • Headless UI: 完全控制你的 Markup 和样式。
  • 轻量级: 压缩后体积小,对性能影响极小。
  • 强大的插件系统: 通过 Hooks 按需引入排序、过滤、分页、分组、行选择等功能。
  • 声明式: 像写 React 组件一样定义你的表格结构。
  • 可扩展: 轻松实现自定义单元格渲染、服务端数据集成等高级功能。

1. 准备工作:环境搭建

在开始之前,请确保你已经有一个基础的 React 项目。如果没有,可以通过 Create React AppVite 快速创建一个:

“`bash

使用 Vite (推荐)

npm create vite@latest my-react-table-app — –template react
cd my-react-table-app
npm install
npm run dev
“`

接下来,安装 react-table 库:

bash
npm install react-table

2. 核心概念:useTable Hook

React Table 的所有魔力都始于 useTable 这个核心 Hook。你需要为它提供两个主要部分:columnsdata

  • data: 一个数组,每个元素都是一个对象,代表表格中的一行数据。
  • columns: 一个数组,定义了表格的列结构。每个列对象至少需要一个 Header (列标题) 和一个 accessor (用于从 data 中匹配数据的键)。

创建你的第一个表格

让我们从一个简单的例子开始。

components/SimpleTable.js

“`jsx
import React, { useMemo } from ‘react’
import { useTable } from ‘react-table’

const SimpleTable = () => {
// 使用 useMemo 确保 data 和 columns 不会在每次渲染时重新创建
// 否则 React Table 会认为接收到了新的数据,导致不必要的计算
const data = useMemo(
() => [
{
col1: ‘Hello’,
col2: ‘World’,
},
{
col1: ‘React Table’,
col2: ‘Rocks’,
},
{
col1: ‘Whatever’,
col2: ‘You want’,
},
],
[]
)

const columns = useMemo(
() => [
{
Header: ‘Column 1’,
accessor: ‘col1’, // accessor 是 data 中每行对象的 key
},
{
Header: ‘Column 2’,
accessor: ‘col2’,
},
],
[]
)

// 使用 useTable hook
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({ columns, data })

// 渲染 UI
return (

{headerGroups.map(headerGroup => (

{headerGroup.headers.map(column => (

))}

))}

{rows.map(row => {
prepareRow(row)
return (

{row.cells.map(cell => (

))}

)
})}

{column.render(‘Header’)}
{cell.render(‘Cell’)}

)
}

export default SimpleTable;
“`

解析 useTable 返回的属性:

  • getTableProps(): 返回 <table> 元素所需的 props。
  • getTableBodyProps(): 返回 <tbody> 元素所需的 props。
  • headerGroups: 一个数组,包含了表头行的信息。如果有多级表头,这个数组会有多个元素。
  • rows: 包含了表格所有行的数组,可以直接用于渲染。
  • prepareRow(row): 这是一个必须调用的函数,在渲染每一行之前执行,用于准备该行所需的 props。

将这个 SimpleTable 组件导入到你的 App.js 中,你就能看到一个基础的、带有样式的表格了!

3. 进阶功能:使用插件 Hooks

React Table 的真正威力在于其插件化的 Hooks 系统。你需要什么功能,就导入对应的 Hook,然后将其作为参数传递给 useTable

3.1 排序 (useSortBy)

让表格支持点击列标题进行排序非常简单。

“`jsx
import { useTable, useSortBy } from ‘react-table’

// …
const {
// … 其他属性
} = useTable(
{ columns, data },
useSortBy // 将 useSortBy Hook 作为第二个参数传入
)

// 在渲染 th 时,增加排序相关的 UI 和 props
// …


{column.render(‘Header’)}
{/* 添加排序指示器 */}

{column.isSorted
? column.isSortedDesc
? ‘ 🔽’
: ‘ 🔼’
: ”}

// …
“`

现在,点击列标题,数据就会自动升序或降序排列。getSortByToggleProps 会自动处理 onClick 事件。

3.2 分页 (usePagination)

当数据量很大时,分页是必不可少的功能。

“`jsx
import { useTable, usePagination } from ‘react-table’

// …
const {
// …
// usePagination 会返回专门用于分页的属性
page, // 当前页的数据,替代原来的 rows
canPreviousPage,
canNextPage,
pageOptions,
pageCount,
gotoPage,
nextPage,
previousPage,
setPageSize,
state: { pageIndex, pageSize },
} = useTable(
{
columns,
data,
initialState: { pageIndex: 0, pageSize: 5 }, // 可以设置初始分页状态
},
usePagination // 启用分页
)

// 渲染分页控制器
return (
<>

{/ … 表格主体,注意用 page 替代 rows … /}

{page.map(row => {
prepareRow(row)
// …
})}

{/ 分页 UI /}

{‘ ‘}
{‘ ‘}
{‘ ‘}
{‘ ‘}

Page{‘ ‘}

{pageIndex + 1} of {pageOptions.length}
{‘ ‘}

{/ … 其他分页控件 … /}

)
“`

3.3 过滤 (useFilters)

React Table 提供了强大的客户端过滤功能。

首先,你需要一个默认的列过滤器 UI 组件。

DefaultColumnFilter.js

“`jsx
// 定义一个默认的 UI
export function DefaultColumnFilter({
column: { filterValue, preFilteredRows, setFilter },
}) {
const count = preFilteredRows.length

return (
{
setFilter(e.target.value || undefined) // 如果输入为空,则设置为 undefined
}}
placeholder={Search ${count} records...}
/>
)
}
“`

然后,在主表格组件中集成它。

“`jsx
import { useTable, useFilters } from ‘react-table’
import { DefaultColumnFilter } from ‘./DefaultColumnFilter’

// …
const defaultColumn = React.useMemo(
() => ({
// 设置默认的 Filter UI
Filter: DefaultColumnFilter,
}),
[]
)

const {
// …
} = useTable(
{
columns,
data,
defaultColumn, // 将 defaultColumn 传入
},
useFilters // 启用过滤
)

// 在表头中渲染过滤器
// …

{headerGroups.map(headerGroup => (

{headerGroup.headers.map(column => (

{column.render(‘Header’)}
{/* 如果列可以过滤,则渲染过滤 UI */}

{column.canFilter ? column.render(‘Filter’) : null}

))}

))}

// …
“`

你还可以为特定列定义不同的过滤方式(例如,下拉选择过滤器 SelectColumnFilter)。

4. 高级技巧

4.1 自定义单元格渲染

accessor 不仅可以是字符串,还可以是一个函数,用于计算派生数据。同时,你可以提供一个 Cell 属性来自定义单元格的渲染内容。

jsx
const columns = useMemo(
() => [
// ...
{
Header: 'Full Name',
// accessor 函数接收原始行数据
accessor: row => `${row.firstName} ${row.lastName}`,
},
{
Header: 'Status',
accessor: 'status',
// Cell 函数接收一个包含 cell 信息的对象
Cell: ({ cell: { value } }) => {
return (
<span style={{
color: value === 'active' ? 'green' : 'red',
fontWeight: 'bold'
}}>
{value}
</span>
)
}
}
],
[]
)

4.2 服务端数据处理

对于海量数据,客户端的排序、分页和过滤会变得非常慢。React Table 完美支持服务端数据处理。你需要做的就是:

  1. useTable 的配置中,设置 manualPagination: true, manualSortBy: true, manualFilters: true
  2. 监听 statepageIndex, pageSize, sortBy, filters 的变化。
  3. 当这些状态变化时,向你的后端 API 发送请求,获取相应的数据。
  4. 将从 API 获取的数据和总页数(pageCount)手动更新到 useTable 中。

这是一个更高级的主题,需要前后端协同工作,但 React Table 已经为你提供了所有必要的工具和状态管理。

总结

React Table 是一个设计精良、功能强大的库。通过其 “headless” 架构和基于 Hooks 的插件系统,它在提供强大功能的同时,也给予了开发者极大的自由度。

从本文的简单表格入门,到集成排序、分页和过滤,再到自定义渲染,你已经掌握了 React Table 的核心用法。接下来,你可以继续探索行选择 (useRowSelect)、列拖拽、虚拟化长列表等更多高级功能。

掌握 React Table,意味着你拥有了在 React 中构建任何复杂数据网格的能力。这无疑是每一位现代前端开发者都应该具备的宝贵技能。

滚动至顶部