React show/hide 自定义 ContextMenu 在切换超过 2 次后滞后

React show/hide custom ContextMenu is lagging after toggling more than 2 times

我想知道为什么我的浏览器在 showing/hiding 我创建的自定义上下文菜单中滞后。

我有一个 React Material table 并以右键单击打开上下文菜单的方式进行了自定义,其中包含 属性 中的项目列表。它按预期运行,但在显示和隐藏该组件几次后,浏览器就死机了。为什么会这样?无论如何有没有办法阻止这种情况发生或有其他方法可以做到这一点?

注意:我已经尝试过 contextMenu 包,但它不能很好地与 MTableRow 覆盖一起使用,这就是我这样做的原因。

import React, { useEffect, useState, forwardRef } from "react";
import MaterialTable, { MTableBodyRow } from "material-table";
import OptionContextMenu from "../OptionContextMenuComponent";

import AddBox from "@material-ui/icons/AddBox";
import ArrowDownward from "@material-ui/icons/ArrowDownward";
import Check from "@material-ui/icons/Check";
import ChevronLeft from "@material-ui/icons/ChevronLeft";
import ChevronRight from "@material-ui/icons/ChevronRight";
import Clear from "@material-ui/icons/Clear";
import DeleteOutline from "@material-ui/icons/DeleteOutline";
import Edit from "@material-ui/icons/Edit";
import FilterList from "@material-ui/icons/FilterList";
import FirstPage from "@material-ui/icons/FirstPage";
import LastPage from "@material-ui/icons/LastPage";
import Remove from "@material-ui/icons/Remove";
import SaveAlt from "@material-ui/icons/SaveAlt";
import Search from "@material-ui/icons/Search";
import ViewColumn from "@material-ui/icons/ViewColumn";

const tableIcons = {
  Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />),
  Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
  Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
  Delete: forwardRef((props, ref) => <DeleteOutline {...props} ref={ref} />),
  DetailPanel: forwardRef((props, ref) => (
    <ChevronRight {...props} ref={ref} />
  )),
  Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
  Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref} />),
  Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
  FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref} />),
  LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
  NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
  PreviousPage: forwardRef((props, ref) => (
    <ChevronLeft {...props} ref={ref} />
  )),
  ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
  Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
  SortArrow: forwardRef((props, ref) => <ArrowDownward {...props} ref={ref} />),
  ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
  ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
};

const initialValue = {
  xPos: "0px",
  yPos: "0px",
  showMenu: false,
  options: []
};

//Show menu based on mouse position

const MyTable = () => {
  const [contextMenuProp, setContextMenuProp] = useState(initialValue);
  const onHandleContextMenu = (e, props) => {
    e.preventDefault();
    let newOptions = { ...contextMenuProp };
    newOptions.xPos = `${e.pageX}px`;
    newOptions.yPos = `${e.pageY}px`;
    newOptions.showMenu = true;
    newOptions.options = props.data.options;
    setContextMenuProp(newOptions);
    console.log("Right clicked", contextMenuProp);
  };

  // Re-hide menu
  const handleClick = (e, props) => {
    e.preventDefault();
    let newOptions = { ...contextMenuProp };
    newOptions.showMenu = false;
    newOptions.options = [];
    setContextMenuProp(newOptions);
    console.log("Left clicked");
  };

  return (
    <>
      <MaterialTable
        title="Dummy table"
        icons={tableIcons}
        columns={[
          { title: "Name", field: "name" },
          { title: "Surname", field: "surname" }
        ]}
        data={[
          { name: "Mehmet", surname: "Baran", options: ["work", "sleep"] },
          { name: "Zerya Betül", surname: "Baran", options: ["run", "walk"] }
        ]}
        options={{
          search: false,
          toolbar: false,
          paging: false,
          sorting: false,
          draggable: false,
          selection: false
        }}
        components={{
          Row: (props) => (
            <MTableBodyRow
              {...props}
              onContextMenu={(e) => onHandleContextMenu(e, props)}
            />
          )
        }}
        onRowClick={(e) => handleClick(e)}
      />
      <OptionContextMenu contextMenuProp={contextMenuProp} />
    </>
  );
};

export default MyTable;

optionContextMenu 组件仅显示正在传递的选项。

示例沙箱:sandbox

我遇到了类似的问题。 material-table 高于 1.67 的版本似乎存在内存泄漏错误。如果带有 table 的页面被多次渲染,这将是内存泄漏。我建议您降级 material-table 版本。

this and this