我正在尝试制作一个可按所有表头排序的可排序用户表。我已经能够让它按升序和降序排序,但只能按名称列。我是 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"];
这是一种通用方法,
在Home组件中,添加一个变量来存储每列的键和类型
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函数
Table
columnHeader
sortData
{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那么我们反转排序。
newUserArr
localeCompare
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> ))}