為什麼我收到「太多重新渲染。React 限制了渲染次數」?我的無限循環在哪裡
P粉946437474
P粉946437474 2023-09-14 12:42:20
0
1
503

我的下面的程式碼運行,但我收到“太多重新渲染”錯誤。我不知道為什麼。如果我取出雙開關並將其基於一個單位(例如價格),那麼它就可以工作。但是,我找不到我的程式碼在哪裡導致無限循環。網路上說我可能錯誤地使用了 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&nbsp;(kg)
            </TableSortLabel></TableCell>

            <TableCell align="center" onClick={handleSortRequest("price")}>
              <TableSortLabel active={true} direction={orderDirection}>
                Price&nbsp;($)
              </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粉946437474
P粉946437474

全部回覆(1)
P粉801904089

您需要傳遞函數引用,而不是直接呼叫函數。 這樣,該函數將僅在事件發生時調用,而不是在元件渲染時立即調用。

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]
  );

希望這些對您有幫助。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板