我的下面的代码运行,但我收到“太多重新渲染”错误。我不知道为什么。如果我取出双开关并将其基于一个单位(例如价格),那么它就可以工作。但是,我找不到我的代码在哪里导致无限循环。网上说我可能错误地使用了 useState 。任何帮助表示赞赏。我是个菜鸟,所以请理解我可能做了一些愚蠢的事情!无论如何,学习是很棒的!谢谢。
import React from "react"; import Table from "@mui/material/Table"; import TableBody from "@mui/material/TableBody"; import TableCell from "@mui/material/TableCell"; import TableContainer from "@mui/material/TableContainer"; import TableHead from "@mui/material/TableHead"; import TableRow from "@mui/material/TableRow"; import Paper from "@mui/material/Paper"; import TableSortLabel from "@mui/material/TableSortLabel"; import { useState } from "react"; function createData(number, item, qty, price) { return { number, item, qty, price }; } const rows = [ createData(1, "Apple", 5, 3), createData(2, "Orange", 2, 2), createData(3, "Grapes", 3, 1), createData(4, "Tomato", 2, 1.6), createData(5, "Mango", 1.5, 4) ]; export default function SortedTable() { const [rowData, setRowData] = useState(rows); const [orderDirection, setOrderDirection] = useState("asc"); const [orderUnit, setOrderUnit] = useState("number"); const sortArray = (arr, orderBy, orderUn) => { switch (orderUn) { case "number": default: switch (orderBy) { case "asc": default: return arr.sort((a, b) => a.number > b.number ? 1 : b.number > a.number ? -1 : 0 ); case "desc": return arr.sort((a, b) => a.number > b.number ? 1 : b.number > a.number ? -1 : 0 ); } case "item": switch (orderBy) { case "asc": default: return arr.sort((a, b) => a.item > b.item ? 1 : b.item > a.item ? -1 : 0 ); case "desc": return arr.sort((a, b) => a.item < b.item ? 1 : b.item < a.item ? -1 : 0 ); } case "qty": switch (orderBy) { case "asc": default: return arr.sort((a, b) => a.qty > b.qty ? 1 : b.qty > a.qty ? -1 : 0 ); case "desc": return arr.sort((a, b) => a.qty < b.qty ? 1 : b.qty < a.qty ? -1 : 0 ); } case "price": switch (orderBy) { case "asc": default: return arr.sort((a, b) => a.price > b.price ? 1 : b.price > a.price ? -1 : 0 ); case "desc": return arr.sort((a, b) => a.price < b.price ? 1 : b.price < a.price ? -1 : 0 ); } } }; const handleSortRequest = (unit) => { setOrderUnit(orderUnit === unit); setRowData(sortArray(rows, orderDirection, orderUnit)); setOrderDirection(orderDirection === "asc" ? "desc" : "asc"); }; return ( <TableContainer component={Paper}> <Table aria-label="simple table" > <TableHead> <TableRow> <TableCell align="center" onClick={handleSortRequest("number")}><TableSortLabel active={true} direction={orderDirection}> S.No </TableSortLabel></TableCell> <TableCell align="center" onClick={handleSortRequest("item")}><TableSortLabel active={true} direction={orderDirection}> Item </TableSortLabel></TableCell> <TableCell align="center" onClick={handleSortRequest("qty")}><TableSortLabel active={true} direction={orderDirection}> Quantity (kg) </TableSortLabel></TableCell> <TableCell align="center" onClick={handleSortRequest("price")}> <TableSortLabel active={true} direction={orderDirection}> Price ($) </TableSortLabel> </TableCell> </TableRow> </TableHead> <TableBody> {rowData.map((row) => ( <TableRow key={row.number}> <TableCell width="100" component="td" scope="row" align="center"> {row.number} </TableCell> <TableCell align="center">{row.item}</TableCell> <TableCell align="center">{row.qty}</TableCell> <TableCell align="center">{row.price}</TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> ); }
我正在尝试使每一列都可以根据单击的列进行排序。额外的问题,为什么我的标题在渲染时与下面的列不匹配。
P粉8019040892023-09-15 11:54:02
您需要传递函数引用,而不是直接调用函数。 这样,该函数将仅在事件发生时调用,而不是在组件渲染时立即调用。
onClick={() => handleSortRequest("item")}
我还重构了您的 sortArray 函数以使其可读。如果是错的。请不要打扰它。 :D
const sortArray = useCallback((arr, orderBy, orderUn) => { const compare = (a, b, prop, order) => { if (order === "asc") { return a[prop] > b[prop] ? 1 : b[prop] > a[prop] ? -1 : 0; } else { return a[prop] < b[prop] ? 1 : b[prop] < a[prop] ? -1 : 0; } }; switch (orderUn) { case "number": default: return arr.sort((a, b) => compare(a, b, "number", orderBy)); case "item": return arr.sort((a, b) => compare(a, b, "item", orderBy)); case "qty": return arr.sort((a, b) => compare(a, b, "qty", orderBy)); case "price": return arr.sort((a, b) => compare(a, b, "price", orderBy)); } }, []);
使用 useCallback 来防止在依赖关系未更改时不必要地重新渲染
const handleSortRequest = useCallback( (unit) => { setOrderUnit(orderUnit === unit); setRowData(sortArray(rows, orderDirection, orderUnit)); setOrderDirection(orderDirection === "asc" ? "desc" : "asc"); }, [orderDirection, orderUnit, sortArray] );
希望这些对您有帮助。