如何实现带有排序的React表

500 阅读3分钟

在本教程中,我想告诉你如何使用React表库及其useSort插件来实现用户排序。在前面的例子中,你安装了React表库来创建一个表组件。现在,你将使你的用户能够通过点击一列的标题对表中的列进行排序

首先,导入useSort钩子:

import { useSort } from '@table-library/react-table-library/sort';

第二,用表的数据初始化该钩子,并将其作为插件道具传递给表组件:

const App = () => {  const data = { nodes: list };
  const sort = useSort(data);
  return (    <Table data={data} sort={sort}>      ...    </Table>  );};

第三,将你的页眉列转换为可排序的页眉列:

import {  useSort,  HeaderCellSort ,} from '@table-library/react-table-library/sort';
const App = () => {  ...
  return (    <Table data={data} sort={sort}>      {(tableList) => (        <>          <Header>            <HeaderRow>              <HeaderCellSort sortKey="TASK">                Task              </HeaderCellSort>              <HeaderCellSort sortKey="DEADLINE">                Deadline              </HeaderCellSort>              <HeaderCellSort sortKey="TYPE">                Type              </HeaderCellSort>              <HeaderCellSort sortKey="COMPLETE">                Complete              </HeaderCellSort>            </HeaderRow>          </Header>
          <Body>            ...          </Body>        </>      )}    </Table>  );};

第四,为每个排序键创建排序函数:

const App = () => {  const data = { nodes: list };
  const sort = useSort(data, null, {    sortFns: {      TASK: (array) =>        array.sort((a, b) => a.name.localeCompare(b.name)),      DEADLINE: (array) =>        array.sort((a, b) => a.deadline - b.deadline),      TYPE: (array) =>        array.sort((a, b) => a.type.localeCompare(b.type)),      COMPLETE: (array) =>        array.sort((a, b) => a.isComplete - b.isComplete),    },  });
  return (    <Table data={data} sort={sort}>      ...    </Table>  );};

这就是了。只用了几行代码,你就实现了按用户排序的表。你可以按字符串(按字母顺序)排序,按日期排序,按布尔值排序,以及按枚举排序。由于你是自己传递排序函数,所以由你来写代码对某一列进行排序。

现在让我们创建一个通知器,从表中获取当前的排序。让我们看看这如何与useSort钩子一起工作。

const App = () => {  const data = { nodes: list };
  const sort = useSort(data,    {      onChange: onSortChange,    }, {      sortFns: ...,    }  );
  function onSortChange(action, state) {    console.log(action, state);  }
  ...};

onChange回调函数让你可以访问触发排序变化的动作和你的表的当前排序状态。有了对这些信息的访问,你就可以在此基础上触发更多的表或非表事件(例如,一个副作用,如服务器端排序)。

此外,值得注意的是,你传递给表的排序对象包含了排序状态--这使你有能力在任何时候访问它--以及所有以编程方式对列进行排序的函数。我们将在后面的React表格中使用自定义排序组件时详细了解这一点。


一个表格的列排序往往还有很多要求。让我们看一下其中的两个。

例如,有时用户希望有一个初始的排序状态。这也可以用useSort钩子来实现,通过传入一个默认的排序状态

const App = () => {  ...
  const sort = useSort(data,    {      state: {        sortKey: 'TASK',        reverse: false,      },      onChange: onSortChange,    }, {      sortFns: ...,    }  );
  ...};

另一个例子是用第三方库(如Material UI)中的自定义排序图标来交换排序图标。

import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
const App = () => {  ...
  const sort = useSort(    data,    {      onChange: onSortChange,    },    {      sortIcon: {        margin: '0px',        iconDefault: <UnfoldMoreOutlinedIcon />,        iconUp: <KeyboardArrowUpOutlinedIcon />,        iconDown: (          <KeyboardArrowDownOutlinedIcon />        ),      },      sortFns: ...    }  );
  ...};

对于排序功能还有很多选择。阅读React表库文档可以了解到更多信息:


最后,通过React表库,可以用自定义组件完全取代排序组件。在表格排序插件的情况下,你可能想用你自己的第三方库中的HTML按钮来替换排序标题组件。下面的例子展示了如何在React表库中使用Material UI组件。

首先,从你的第三方库中导入自定义组件(和自定义图标):

import MaterialButton from '@mui/material/Button';import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';

其次,将第三方按钮用于表头。

const App = () => {  ...
  const getIcon = (sortKey) => {    if (sort.state.sortKey === sortKey && sort.state.reverse) {      return <KeyboardArrowDownOutlinedIcon />;    }
    if (sort.state.sortKey === sortKey && !sort.state.reverse) {      return <KeyboardArrowUpOutlinedIcon />;    }
    return <UnfoldMoreOutlinedIcon />;  };
  return (    <Table data={data} sort={sort}>      {(tableList) => (        <>          <Header>            <HeaderRow>              <HeaderCell>                <MaterialButton                  fullWidth                  style={{ justifyContent: 'flex-start' }}                  endIcon={getIcon('TASK')}                  onClick={() =>                    sort.fns.onToggleSort({                      sortKey: 'TASK',                    })                  }                >                  Task                </MaterialButton>              </HeaderCell>
              ...
            </HeaderRow>          </Header>
          <Body>            ...          </Body>        </>      )}    </Table>  );};

注意来自useSort钩子的排序对象如何为你提供创建自定义组件所需的一切。通过这种方式,你可以为每个表列定制排序组件。有了排序状态和所有的排序函数供你使用,你可以从任何地方读取和写入排序状态。


这就是你需要了解的关于React表库的排序插件的一切。如果你有反馈意见,请在GitHub仓库里开一个问题。如果你想阅读更多关于React表库的信息,请查看其文档