本文完整版:《React Table 表格组件应用教程 排序、分页、搜寻过滤筛选性能实战开发》

在日常开发中,特地是外部应用的后盾零碎时,咱们经常会须要用表格来展现数据,同时提供一些操作用于操作表格内的数据。简略的表格间接用原生 HTML table 就好,但如果要在 React 中实现一个功能丰富的表格,其实是十分不容易的。

在本站之前的文章《最好的 6 个 React Table 组件具体亲测举荐》 中有提到过 react-table 这个库,如果对这个库不太理解的同学能够先理解一下,这里不再赘述。

简而言之,react-table 是一个十分弱小的库,它与常见的表格组件不同,它不负责渲染 HTML 和 CSS,而是提供了一系列的 hooks 让咱们能够灵便地构建功能强大的表格组件。

因而应用 react-table 进行开发具备肯定的难度,而本文将由浅入深地解说如何在 React 我的项目中应用 react-table 实现各种常见的需要,例如:排序、分页、搜寻过滤筛选等;同时还会联合一个残缺的案例给大家解说如何搭配应用 Material-UI 以及模仿从后端获取数据进行分页等性能。

如果你正在搭建后盾管理工具,又不想解决前端问题,举荐应用卡拉云 ,卡拉云是新一代低代码开发工具,可一键接入常见数据库及 API,内置表格等常见的前端组件,无需懂前端,仅需拖拽即可疾速搭建属于你本人的后盾管理工具,一周工作量缩减至一天,详见本文文末。

追随本文你将学到

  • 如何应用 react-table 在 React 中搭建表格组件
  • 如何应用 react-table 表格组件进行数据的分页、排序、搜寻过滤筛选
  • react-table 实战案例:手把手教你应用 react-table 表格组件实战分页、排序、搜寻过滤筛选

扩大浏览:《顶级好用的 React 表单设计生成器,可拖拽生成表单》

react-table 装置和应用

首先,让咱们先来创立一个 React 我的项目:

npx create-react-app react-table-democd react-table-demo

而后咱们装置一下 react-table:

接下来咱们通过一个简略的示例,解说如何在 React 我的项目中应用 react-table。

假如咱们有一个订单表:

订单编号姓名收货地址下单日期
1596694478675759682蒋铁柱北京市海淀区西三环中路19号2022-07-01
1448752212249399810陈胜利湖北武汉武昌区天子家园2022-06-27
1171859737495400477宋阿美湖北武汉武昌区天子家园2022-06-21
1096242976523544343张小乐北京市海淀区北航南门2022-06-30
1344783976877111376马国庆北京市海淀区花园桥西北2022-06-12
1505069508845600364小果广州天河机场西侧停车场2022-06-07

咱们应用 react-table 时,须要通过一个叫做 useTable 的 hooks 来构建表格。

import { useTable } from 'react-table'

useTable 接管两个必填的参数:

  1. data:表格的数据
  2. columns:表格的列

所以让咱们先来定义这个订单表的 data 和 columns:

import React, { useMemo } from 'react'function App() {  const data = useMemo(    () => [      {        name: '蒋铁柱',        address: '北京市海淀区西三环中路19号',        date: '2022-07-01',        order: '1596694478675759682'      },      {        name: '陈胜利',        address: '湖北武汉武昌区天子家园',        date: '2022-06-27',        order: '1448752212249399810'      },      {        name: '宋阿美',        address: '湖北武汉武昌区天子家园',        date: '2022-06-21',        order: '1171859737495400477'      },      {        name: '张小乐',        address: '北京市海淀区北航南门',        date: '2022-06-30',        order: '1096242976523544343'      },      {        name: '马国庆',        address: '北京市海淀区花园桥西北',        date: '2022-06-12',        order: '1344783976877111376'      },      {        name: '小果',        address: '广州天河机场西侧停车场',        date: '2022-06-07',        order: '1505069508845600364'      }    ],    []  )  const columns = useMemo(    () => [      {        Header: '订单编号',        accessor: 'order'      },      {        Header: '姓名',        accessor: 'name'      },      {        Header: '收货地址',        accessor: 'address'      },      {        Header: '下单日期',        accessor: 'date'      }    ],    []  )  return (    <div>      <h1>React Table Demo —— 卡拉云(https://kalacloud.com)</h1>      <Table columns={columns} data={data}></Table>    </div>  )}

你可能会留神到这里咱们应用 useMeno 来申明数据,这是因为 react-table 文档中阐明传入的 data 和 columns 必须是 memoized 的,简略来说就是能够缓存的,仅当依赖项数组外面的依赖发生变化时才会从新计算,如果对 useMemo 不相熟的同学倡议间接看 React 文档。

接着咱们构建一个 Table 组件接管 columns 和 data,并传入到 useTable 中,它会返回一系列属性,咱们就能够利用这些属性来构建 HTML table:

function Table({ columns, data }) {  const {    getTableProps,    getTableBodyProps,    headerGroups,    rows,    prepareRow,  } = useTable({    columns,    data,  })  return (    <table {...getTableProps()}>      <thead>        {headerGroups.map((headerGroup) => (          <tr {...headerGroup.getHeaderGroupProps()}>            {headerGroup.headers.map((column) => (              <th {...column.getHeaderProps()}>{column.render('Header')}</th>            ))}          </tr>        ))}      </thead>      <tbody {...getTableBodyProps()}>        {rows.map((row, i) => {          prepareRow(row)          return (            <tr {...row.getRowProps()}>              {row.cells.map((cell) => {                return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>              })}            </tr>          )        })}      </tbody>    </table>  )}

因为是应用原生的 HTML table,因而是没有任何款式的, 这也是 react-table 的特点,益处是咱们能够随便自定义咱们想要的款式,比方咱们引入 github-markdown-css

npm i github-markdown-css

而后在我的项目中应用即可:

import React, { useMemo } from 'react'import { useTable } from 'react-table'import './App.css'+ import 'github-markdown-css'function App() {  return (-   <div>+   <div className="markdown-body" style={{ padding: '20px' }}>      <h1>React Table Demo —— 卡拉云(https://kalacloud.com)</h1>      <Table columns={columns} data={data}></Table>    </div>  )}

react-table 款式成果:

接下来咱们给这个表格增加更多常见的性能:排序、搜寻过滤筛选、分页等。

扩大浏览:《7 款最棒的开源 React 挪动端 UI 组件库和模版框架 - 特地针对国内应用场景举荐》

React Table 表格排序功能

如果只是想设置默认排序,咱们能够通过配置 initialState 来实现:

useTable({  columns,  data,  initialState: {    sortBy: [      {        id: 'order',        desc: true      }    ]  }})

如果要实现手动排序,就须要通过 useSortBy 这个 hooks 实现:

import { useTable, useSortBy } from 'react-table' 

而后在 useTable 中传入 useSortBy

const {  getTableProps,  getTableBodyProps,  headerGroups,  rows,  prepareRow,} = useTable( {   columns,   data, },+ useSortBy,)

而后咱们能够在 columns 中的某个列指定 sortType 属性,它接管 String 或 Function,对于 Function 的应用形式按下不表,而对于 String 类型,它能够接管以下三种:

  1. alphanumeric:字母或数字进行排序(默认值)
  2. basic:0 到 1 之间的数字排序
  3. datetime:日期排序,值必须为 Date 类型

比方在咱们这个例子中,咱们心愿能够容许对「订单编号」进行排序,那咱们则批改:

const columns = useMemo(  () => [    {      Header: '订单编号',      accessor: 'order',+     sortType: 'basic'    },    {      Header: '姓名',      accessor: 'name'    },    {      Header: '收货地址',      accessor: 'address'    },    {      Header: '下单日期',      accessor: 'date',    }  ],  [])

接着咱们在表头处中增加排序相干的逻辑,并且依据当前列的排序状况别离显示对应的箭头,或者在没有任何排序时不显示:

<thead>  {headerGroups.map((headerGroup) => (  <tr {...headerGroup.getHeaderGroupProps()}>    {headerGroup.headers.map((column) => (-   <th {...column.getHeaderProps()}>+   <th {...column.getHeaderProps(column.getSortByToggleProps())}>      {column.render('Header')}+     <span>+       {column.isSorted ? (column.isSortedDesc ? ' ' : ' ') : ''}+     </span>    </th>    ))}  </tr>  ))}</thead>

展现成果如下:

通过上图咱们发现了一个问题:即使咱们没有对「姓名」这一列配置 sortType,却仍然能够进行排序,这是因为一旦在 useTable 传入了 useSortBy,则默认所有列都可进行排序,如果咱们须要对特定的列禁用排序,能够这样:

const columns = useMemo(  () => [    {      Header: '订单编号',      accessor: 'order',      sortType: 'basic'    },    {      Header: '姓名',      accessor: 'name',+     disableSortBy: true,    },    {      Header: '收货地址',      accessor: 'address'    },    {      Header: '下单日期',      accessor: 'date',    }  ],  [])

对于排序功能更多具体细节参见文档:useSortBy。

扩大浏览:《7 款最棒的开源 React UI 组件库和模版框架测评 - 特地针对国内应用场景举荐》

React Table 表格搜寻过滤筛选性能

咱们能够通过 useFilters 来实现筛选性能:

import { useTable, useFilters } from 'react-table'

同样地,须要在 useTable 中传入:

const {  getTableProps,  getTableBodyProps,  headerGroups,  rows,  prepareRow,} = useTable( {   columns,   data, },+ useFilters,)

PS:留神 useFilters 必须位于 useSortBy 后面,否则会报错。

而后在表头中渲染筛选输入框:

<th {...column.getHeaderProps()}> {column.render('Header')}+ <div>{column.canFilter ? column.render('Filter') : null}</div></th>

这个筛选输入框的 UI 须要咱们自定义,所以咱们定义一个 TextFilter 组件:

function TextFilter({ column: { filterValue, preFilteredRows, setFilter } }) {  const count = preFilteredRows.length  return (    <input      value={filterValue || ''}      onChange={(e) => {        setFilter(e.target.value || undefined)      }}      placeholder={`筛选 ${count} 条记录`}    />  )}

这个组件接管三个参数:

  • filterValue:用户输出的筛选值
  • preFilteredRows:筛选前的行
  • setFilter:用于设置用户筛选的值

定义完筛选组件后,咱们还将 TextFilter 传入到一个 defaultColumn 中:

const defaultColumn = React.useMemo( () => ({   Filter: TextFilter, }), [])

接着再把 defaultColumn 传入 useTable

const {  getTableProps,  getTableBodyProps,  headerGroups,  rows,  prepareRow,} = useTable( {   columns,   data,+  defaultColumn, }, useFilters,)

展现成果如下:

这里咱们发现了一个问题:当点击筛选输入框时,会扭转排序形式,这是因为扭转排序的点击事件是放在 <th>,因而咱们要阻止这个输入框的点击事件向外层冒泡:

- <div>+ <div onClick={(e) => e.stopPropagation()}>    {column.canFilter ? column.render('Filter') : null}</div>

同样地,如果想要禁用某一个列的筛选,能够设置 disableFilters

const columns = useMemo(  () => [    {      Header: '订单编号',      accessor: 'order',      sortType: 'basic'    },    {      Header: '姓名',      accessor: 'name',+     disableFilters: true,    },    {      Header: '收货地址',      accessor: 'address'    },    {      Header: '下单日期',      accessor: 'date',    }  ],  [])

对于筛选性能更多具体细节参见文档:useFilters。

扩大浏览:《最好用的 8 款 React Datepicker 工夫日期选择器测评举荐》

React Table 表格分页性能

分页性能应用 usePagination 这个 hooks 实现:

import { useTable, usePagination } from 'react-table' 

而后在 useTable 中增加分页相干的参数:

const {   getTableProps,   headerGroups,   getRowProps,-  rows +  state: { pageIndex, pageSize },+  canPreviousPage,+  canNextPage,+  previousPage,+  nextPage,+  pageOptions,+  page } = useTable(   {     columns,     data,+    initialState: { pageSize: 2 },   },+  usePagination, )

而后咱们 tbody 中的 rows 将从 page 变量中获取:

<tbody {...getTableBodyProps()}>- {rows.map((row) => {+ {page.map((row) => {      prepareRow(row)  return (    <tr {...row.getRowProps()}>      {row.cells.map((cell) => {        return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>      })}    </tr>  )})}</tbody>

咱们还须要构建一个分页器:

function Pagination({  canPreviousPage,  canNextPage,  previousPage,  nextPage,  pageOptions,  pageIndex}) {  return (    <div>      <button onClick={() => previousPage()} disabled={!canPreviousPage}>        上一页      </button>{' '}      <button onClick={() => nextPage()} disabled={!canNextPage}>        下一页      </button>      <div>        第{' '}        <em>          {pageIndex + 1} / {pageOptions.length}        </em>{' '}        页      </div>    </div>  )}

在 table 前面应用这个分页器:

<>  <table {...getTableProps()}>...  </table>  <Pagination    canPreviousPage={canPreviousPage}    canNextPage={canNextPage}    previousPage={previousPage}    nextPage={nextPage}    pageOptions={pageOptions}    pageIndex={pageIndex}  /></>

展现成果如下:

更简单的分页能够参考官网示例:Examples: Pagination。

扩大浏览:《最好用的 5 个 React select 多选下拉菜单组件测评举荐》

React table 排序、搜寻过滤筛选、分页示例代码

通过前文咱们曾经把 react-table 的根本应用都演示了一遍,你能够在此获取示例代码。

React table 实战案例

然而理论开发中的需要天然不会满足于本地数据,因而接下来咱们演示一个更加实在、残缺的例子,它将蕴含以下性能:

  1. 模仿从远端申请数据,并且通过服务端进行分页、筛选、排序。
  2. 搭配 Material-UI 构建组件

首先创立一个新的我的项目:

npx create-react-app react-table-examplecd react-table-example

而后装置相干依赖:

npm i react-table mockjs axios lodash.orderbynpm i axios-mock-adapter --save-devnpm i @material-ui/core @material-ui/icons

模仿 API

而后咱们生成 200 条订单数据,同时模仿 API 的筛选、排序和分页性能:

// mock.jsimport axios from 'axios'import MockAdapter from 'axios-mock-adapter'import Mock from 'mockjs'import _orderby from 'lodash.orderby'const { Random, mock } = Mockconst orders = new Array(200).fill(null).map(() => {  return mock({    order: Random.natural(),    name: Random.cname(),    address: Random.province() + '-' + Random.city() + '-' + Random.county(),    date: Random.date()  })})const mockAPI = {  start() {    const mock = new MockAdapter(axios)    mock.onGet('/api/orders').reply((config) => {      let { filter, sortBy, page = 0, size = 10 } = config.params || {}      let mockOrders = [...orders]      if (filter) {        mockOrders = orders.filter((order) => {          return Object.values(order).some((value) => value.includes(filter))        })      }      if (sortBy.length) {        sortBy.forEach((sort) => {          mockOrders = _orderby(            mockOrders,            [sort.id],            [sort.desc ? 'desc' : 'asc']          )        })      }      const offset = page * size      mockOrders = mockOrders.slice(offset, offset + size)      return new Promise((resolve) => {        setTimeout(() => {          resolve([            200,            {              data: mockOrders,              total_count: orders.length            }          ])        }, 500)      })    })  }}export default mockAPI

而后在 App.js 中引入并开始 mock 数据:

import mockAPI from './mock'mockAPI.start()

构建根底 React Table 组件

有了下面的教训,咱们很快就能够构建一个根底的表格组件:

// components/Table.jsimport React from 'react'import { useTable } from 'react-table'import MaUTable from '@material-ui/core/Table'import TableBody from '@material-ui/core/TableBody'import TableCell from '@material-ui/core/TableCell'import TableContainer from '@material-ui/core/TableContainer'import TableHead from '@material-ui/core/TableHead'import TableRow from '@material-ui/core/TableRow'function Table({ columns, data }) {  const { getTableProps, headerGroups, prepareRow, rows } = useTable({    columns,    data  })  return (    <TableContainer>      <MaUTable {...getTableProps()}>        <TableHead>          {headerGroups.map((headerGroup) => (            <TableRow {...headerGroup.getHeaderGroupProps()}>              {headerGroup.headers.map((column) => (                <TableCell {...column.getHeaderProps()}>                  {column.render('Header')}                </TableCell>              ))}            </TableRow>          ))}        </TableHead>        <TableBody>          {rows.map((row, i) => {            prepareRow(row)            return (              <TableRow {...row.getRowProps()}>                {row.cells.map((cell) => {                  return (                    <TableCell {...cell.getCellProps()}>                      {cell.render('Cell')}                    </TableCell>                  )                })}              </TableRow>            )          })}        </TableBody>      </MaUTable>    </TableContainer>  )}export default Table

而后在 App.js 中申请 API 并展现:

import React, { useState, useMemo, useEffect } from 'react'import axios from 'axios'import Table from './components/Table'import mockAPI from './mock'mockAPI.start()function App() {  const fetchOrders = async (params = {}) => {    return axios.get('/api/orders', { params }).then((res) => {      const resp = res.data      setOrders(resp.data)    })  }  const [orders, setOrders] = useState([])  const data = useMemo(() => {    return [...orders]  }, [orders])  const columns = useMemo(    () => [      {        Header: '订单编号',        accessor: 'order'      },      {        Header: '姓名',        accessor: 'name'      },      {        Header: '收货地址',        accessor: 'address'      },      {        Header: '下单日期',        accessor: 'date'      }    ],    []  )    useEffect(() => {    fetchOrders()  }, [])  return (    <div style={{ padding: '20px' }}>      <h1>React Table Example —— 卡拉云(https://kalacloud.com)</h1>      <Table data={data} columns={columns} />    </div>  )}export default App

展现成果如下:

服务端分页

接着咱们增加分页性能,首先增加 TablePaginationActions 组件:

// components/TablePaginationActions.jsimport React from 'react'import FirstPageIcon from '@material-ui/icons/FirstPage'import IconButton from '@material-ui/core/IconButton'import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'import LastPageIcon from '@material-ui/icons/LastPage'import { makeStyles, useTheme } from '@material-ui/core/styles'const useStyles = makeStyles((theme) => ({  root: {    flexShrink: 0,    marginLeft: theme.spacing(2.5)  }}))const TablePaginationActions = (props) => {  const classes = useStyles()  const theme = useTheme()  const { count, page, rowsPerPage, onPageChange } = props  const handleFirstPageButtonClick = (event) => {    onPageChange(event, 0)  }  const handleBackButtonClick = (event) => {    onPageChange(event, page - 1)  }  const handleNextButtonClick = (event) => {    onPageChange(event, page + 1)  }  const handleLastPageButtonClick = (event) => {    onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1))  }  return (    <div className={classes.root}>      <IconButton        onClick={handleFirstPageButtonClick}        disabled={page === 0}        aria-label="first page"      >        {theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}      </IconButton>      <IconButton        onClick={handleBackButtonClick}        disabled={page === 0}        aria-label="previous page"      >        {theme.direction === 'rtl' ? (          <KeyboardArrowRight />        ) : (          <KeyboardArrowLeft />        )}      </IconButton>      <IconButton        onClick={handleNextButtonClick}        disabled={page >= Math.ceil(count / rowsPerPage) - 1}        aria-label="next page"      >        {theme.direction === 'rtl' ? (          <KeyboardArrowLeft />        ) : (          <KeyboardArrowRight />        )}      </IconButton>      <IconButton        onClick={handleLastPageButtonClick}        disabled={page >= Math.ceil(count / rowsPerPage) - 1}        aria-label="last page"      >        {theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}      </IconButton>    </div>  )}export default TablePaginationActions

而后在 Table.js 中批改如下:

import React, { useEffect } from 'react'import { useTable, usePagination } from 'react-table'+ import TableFooter from '@material-ui/core/TableFooter'+ import TablePagination from '@material-ui/core/TablePagination'+ import TablePaginationActions from './TablePaginationActions'- function Table({ columns, data }) {+ function Table({ columns, data, totalCount, onStateChange }) {  const {    getTableProps,    headerGroups,    prepareRow,-   rows,  +   page,+   gotoPage,+   setPageSize,+   state: { pageIndex, pageSize }  } = useTable(    {      columns,      data,+     manualPagination: true,+     pageCount: totalCount    },+   usePagination  )+  useEffect(() => {+    onStateChange({ pageIndex, pageSize })+  }, [pageIndex, pageSize, onStateChange])+  const handleChangePage = (event, newPage) => {+    gotoPage(newPage)+  }+  const handleChangeRowsPerPage = (event) => {+    setPageSize(Number(event.target.value))+  }  return (    <TableContainer>      <MaUTable {...getTableProps()}>...        <TableBody>-         {rows.map((row, i) => {+         {page.map((row, i) => {...        </TableBody>+       <TableFooter>+         <TableRow>+           <TablePagination+             rowsPerPageOptions={[5, 10, 15, 20]}+             colSpan={3}+             count={totalCount}+             rowsPerPage={pageSize}+             page={pageIndex}+             SelectProps={{+               inputProps: { 'aria-label': 'rows per page' },+               native: true+             }}+             onPageChange={handleChangePage}+             onRowsPerPageChange={handleChangeRowsPerPage}+             ActionsComponent={TablePaginationActions}+           />+         </TableRow>+       </TableFooter>      </MaUTable>    </TableContainer>  )}export default Table

App.js 中减少管制分页的逻辑:

const [totalCount, setTotalCount] = useState(0)const fetchOrders = async (params = {}) => {  return axios.get('/api/orders', { params }).then((res) => {    const resp = res.data    setOrders(resp.data)    setTotalCount(resp.total_count)  })}const onStateChange = useCallback(({ pageIndex, pageSize }) => {  fetchOrders({    page: pageIndex,    size: pageSize  })}, [])

因为 Table 组件外部会触发 onStateChange,因而不须要在 useEffect 中获取数据 ,而后传入 Table 相干属性:

- useEffect(() => {-     fetchOrders()-   }, [])<Table  data={data}  columns={columns}+ totalCount={totalCount}+ onStateChange={onStateChange}/>

展现成果如下:

服务端排序

接着咱们增加排序功能,首先批改 Table.js

- import { useTable, usePagination } from 'react-table'+ import { useTable, usePagination, useSortBy } from 'react-table'+ import TableSortLabel from '@material-ui/core/TableSortLabel'function Table({ columns, data, totalCount, onStateChange }) {  const {    getTableProps,    headerGroups,    prepareRow,    page,    gotoPage,    setPageSize,-   state: { pageIndex, pageSize }    +   state: { pageIndex, pageSize, sortBy }  } = useTable(    {      columns,      data,      manualPagination: true,+     manualSortBy: true,      pageCount: totalCount    },+   useSortBy,    usePagination  )  -  useEffect(() => {-    onStateChange({ pageIndex, pageSize })-  }, [pageIndex, pageSize, onStateChange])+  useEffect(() => {+    onStateChange({ pageIndex, pageSize, sortBy })+  }, [pageIndex, pageSize, sortBy, onStateChange])    <TableCell-     {...column.getHeaderProps()}+     {...column.getHeaderProps(column.getSortByToggleProps())}    >       {column.render('Header')}+     <TableSortLabel+       active={column.isSorted}+       direction={column.isSortedDesc ? 'desc' : 'asc'}+     />    </TableCell>}

React table 排序功能展现成果如下:

扩大浏览:《React 实现 PDF 文件在线预览 - 手把手教你写 React PDF 预览性能》

服务端搜寻过滤筛选

而后咱们增加筛选性能,通常筛选器都是位于表格以外的,在本例子中,咱们期待在筛选框中输出的搜寻值利用在所有的列,这里咱们创立一个 TableFilter 组件:

// components/TableFilter.jsimport React from 'react'import InputBase from '@material-ui/core/InputBase'import { fade, makeStyles } from '@material-ui/core/styles'import SearchIcon from '@material-ui/icons/Search'const useStyles = makeStyles((theme) => ({  search: {    position: 'relative',    borderRadius: theme.shape.borderRadius,    backgroundColor: fade(theme.palette.common.white, 0.15),    '&:hover': {      backgroundColor: fade(theme.palette.common.white, 0.25)    },    marginRight: theme.spacing(2),    marginLeft: 0,    width: '100%',    [theme.breakpoints.up('sm')]: {      width: 'auto'    }  },  searchIcon: {    width: theme.spacing(7),    height: '100%',    position: 'absolute',    pointerEvents: 'none',    display: 'flex',    alignItems: 'center',    justifyContent: 'center'  },  inputRoot: {    color: 'inherit'  },  inputInput: {    padding: theme.spacing(1, 1, 1, 7),    transition: theme.transitions.create('width'),    width: '100%',    [theme.breakpoints.up('md')]: {      width: 200    }  }}))const GlobalFilter = ({ globalFilter, setGlobalFilter }) => {  const classes = useStyles()  return (    <div className={classes.search}>      <div className={classes.searchIcon}>        <SearchIcon />      </div>      <InputBase        value={globalFilter || ''}        onChange={(e) => {          setGlobalFilter(e.target.value || undefined)        }}        placeholder={`在此输出搜寻值`}        classes={{          root: classes.inputRoot,          input: classes.inputInput        }}        inputProps={{ 'aria-label': 'search' }}      />    </div>  )}export default GlobalFilter

而后在 Table.js 中应用这个组件,并增加筛选逻辑:

- import { useTable, usePagination, useSortBy } from 'react-table'+ import { useTable, usePagination, useSortBy, useGlobalFilter } from 'react-table'+ import TableFilter from './TableFilters'function Table({ columns, data, totalCount, onStateChange }) {  const {    getTableProps,    headerGroups,    prepareRow,    page,    gotoPage,    setPageSize,-   state: { pageIndex, pageSize, sortBy }    +   state: { pageIndex, pageSize, sortBy, globalFilter },+   setGlobalFilter  } = useTable(    {      columns,      data,      manualPagination: true,      manualSortBy: true,+     manualGlobalFilter: true,      pageCount: totalCount    },+   useGlobalFilter,    useSortBy,    usePagination  )    useEffect(() => {-   onStateChange({ pageIndex, pageSize, sortBy })+   onStateChange({ pageIndex, pageSize, sortBy, filter: globalFilter })- }, [pageIndex, pageSize, sortBy, onStateChange])+ }, [pageIndex, pageSize, sortBy, onStateChange, globalFilter])        <TableContainer>+     <TableFilter+       globalFilter={globalFilter}+       setGlobalFilter={setGlobalFilter}+     />  

App.js 中接管 filter 值并传递给 API:

const onStateChange = useCallback(- ({ pageIndex, pageSize, sortBy }) => {+ ({ pageIndex, pageSize, sortBy, filter }) => {    fetchOrders({      page: pageIndex,      size: pageSize,      sortBy,+     filter    })  },  [])

react-table 搜寻过滤筛选展现成果如下:

扩大浏览:《5款 React 实时音讯提醒告诉(Message/Notification)组件举荐与测评》

React Table 组件与卡拉云

后面咱们展现了如何在 react-table 中搭配 Material-UI 构建一个残缺的表格组件,置信你曾经上手 react-table 的用法,而这只是 react-table 性能的冰山一角,还有更多例如:动静展现列、分组开展、动画、拖拽、行内编辑、虚构列表等,所以 react-table 的弱小能够让你搭配出更多自定义性能。

其实如果你只想专一在解决问题,而不想把工夫节约在调试前端问题上的话,举荐应用卡拉云,卡拉云是新一代低代码开发工具,不仅能够拖拽生成带有排序、分页、搜寻性能的表格组件等多种你须要的前端组件。与各类前端框架相比,卡拉云齐全不必写前端代码,极大晋升了开发效率,1 周的工作量,当初只有 30 分钟即可实现。卡拉云间接注册即可开始应用,后盾搭建实现后,还能一键分享给共事一起应用。

可一键分享给共事一起应用:https://my.kalacloud.com/apps/q6p23cqa29/published

卡拉云可帮你疾速搭建企业外部工具,下图为应用卡拉云搭建的外部广告投放监测零碎,无需懂前端,仅需拖拽组件,10 分钟搞定。你也能够疾速搭建一套属于你的后盾管理工具。

卡拉云是新一代低代码开发平台,与前端框架 Vue、React等相比,卡拉云的劣势在于不必首先搭建开发环境,间接注册即可开始应用。开发者齐全不必解决任何前端问题,只需简略拖拽,即可疾速生成所需组件,可一键接入常见数据库及 API,依据疏导简略几步买通前后端,数周的开发工夫,缩短至 1 小时。立刻收费试用卡拉云。