一尘不染

单击表头时排序表

javascript

我正在尝试制作一个可按所有表头排序的可排序用户表。我已经能够让它按升序和降序排序,但只能按名称列。我是 reactjs 的新手,无法在我的代码中实现它。

这是表格组件:

import { formatDate } from "../../utils/formatDate";
import "./table.css";

function Table(props) {
  const { headerData, bodyData, removeItem, sortData, ordIcon} = props;


  return (
    <div className="user-data">
      <table className="user-table">
        <thead>
          <tr className="data-th">
            {headerData.map((headerTable) => (
              <th onClick={sortData} id={"header-"+headerTable.toLowerCase()}>
                {headerTable} <img src={ordIcon} id="arrow-img"></img>
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {bodyData.map((item) => (
            <tr className="data-tr">
              <td>{item.name}</td>
              <td>{item.email}</td>
              <td>{item.occupation}</td>
              <td>{formatDate(item.birthday)}</td>               
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

export default Table;

这是主页中的排序代码:

const sortData = () => {

    if (order === "" || "asc") {
      let sortUserName = [...newUserArr].sort((a, b) =>
        a.name.localeCompare(b.name)
      );
      setOrder("dsc");
      setNewUserArr(sortUserName);
      setOrdIcon(arrowDown)
    } if (order === "dsc") {
      let sortUserName = [...newUserArr].sort((a, b) =>
        b.name.localeCompare(a.name)
      );
      setOrder("asc");
      setNewUserArr(sortUserName);
      setOrdIcon(arrowUp)
    }
  };

谢谢

编辑:headerData={headerUser}

const headerUser = ["Name", "Email", "Occupation", "Birthday"];

阅读 84

收藏
2022-07-26

共1个答案

一尘不染

这是一种通用方法,

Home组件中,添加一个变量来存储每列的键和类型

    const columnMap = {
        Name: {key: 'name', type: 'string'},
        Email: {key: 'email', type: 'string'},
        Occupation: {key: 'occupation', type: 'string'},
        Birthday: {key: 'birthday', type: 'date'}
    };

然后在Table组件中渲染列标题时,更改 onClick 以便它发送columnHeadertosortData函数

{headerData.map((headerTable) => (
  <th onClick={() => sortData(headerTable)} id={"header-"+headerTable.toLowerCase()}>
     {headerTable} <img src={ordIcon} id="arrow-img"></img>
  </th>
))}

最后在sortData函数中,

const sortData = (columnHeader) => {
    const {key, type} = columnMap[columnHeader];

    const sorted = [...newUserArr].sort((a, b) => {
        let sortValue = 0;

        if (type === 'date') {
            sortValue = new Date(a[key]) - new Date(b[key]);
        } else {
            sortValue = a[key].localeCompare(b[key]);
        }

        return order === 'dsc' ? -(sortValue) : sortValue;
    });

    setNewUserArr(sorted);

    if (order === '' || 'asc') {
        setOrder('dsc');
        setOrdIcon(arrowDown);
    } else {
        setOrder('asc');
        setOrdIcon(arrowUp);
    }    
};

我们首先找到需要排序的键newUserArr,我们还需要在这里输入,因为我们不能使用日期localeCompare。然后我们对数组进行排序,如果 order 是dsc那么我们反转排序。

编辑 - 对于排序图标,我们可以跟踪每列的当前排序状态,然后在Table组件中使用它

Home组件中

const [sortStatus, setSortStatus] = useState({});

并更改sortData

const sortData = (columnHeader) => {
    const {key, type} = columnMap[columnHeader];

    const sorted = [...newUserArr].sort((a, b) => {
        let sortValue = 0;

        if (type === 'date') {
            sortValue = new Date(a[key]) - new Date(b[key]);
        } else {
            sortValue = a[key].localeCompare(b[key]);
        }

        return order === 'dsc' ? -(sortValue) : sortValue;
    });

    setNewUserArr(sorted);

    setSortStatus((prev) => ({
        ...prev,
        [columnHeader]: order === 'dsc' ? 'asc' : 'dsc'
    }))
};

Table组件中,

const getSortIcon = (columnHeader) => {
   if (!sortStatus[columnHeader]) {
      return "↕︎";
   }

   return sortStatus[columnHeader] === 'dsc' ? "↓" : "↑"; 
};

{headerData.map((headerTable) => (
    <th onClick={sortData} id={"header-"+headerTable.toLowerCase()}>
    {headerTable}
    {getSortIcon(headerTable)}
    </th>
))}
2022-07-26