首页 > 解决方案 > 使用对话框中的状态按钮或 Material UI 中的警报来反应内存泄漏警告

问题描述

我正在将 Material UI 用于组件库,并注意到当我单击对话框或警报中的按钮(两个组件都管理打开/关闭状态)时,我收到了内存泄漏警告。我不确定如何解决这里的问题。按钮组件在单击时使用状态创建一个活动类,该类使用setTimeoutonClick 使按钮单击在 UI 中更可见/更持久。

这是按钮组件:

function Button({
  classes,
  className,
  onClick,
  ...props
}) {
  let [active, setActive] = useState(false);

  let handleClick = e => {
    e.persist();
    setActive(true);
    setTimeout(() => {
      setActive(false);
    }, 250);
  if (typeof onClick === "function") onClick(e);
  };

  return (
    <MuiButton
      variant={finalVariant(variant)}
      className={`${active ? "Mui-active" : ""} ${className}`}
      classes={buttonClasses}
      onClick={handleClick}
      {...props}
    />
  );
}

let containedStyle = color => ({
  "&:active": {
    backgroundColor: color.dark
  },
  "&.Mui-active": {
    backgroundColor: color.dark
  }
});

这是我在单击警报或对话框组件中的按钮时收到的内存泄漏警告:

index.js:1437 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

我已经尝试useEffect按照警告的建议使用来清除活动状态,但没有运气。这是一个演示,当我使用使用 MUI 构建的自定义按钮时会发生什么,当按钮在对话框或警报中使用时使用钩子来管理状态https://codesandbox.io/s/traffic-light-using-hooks- zpfrc?fontsize=14&hidenavigation=1&theme=dark

标签: reactjsmaterial-uistatereact-hooksjss

解决方案


这是我对这个问题的解决方案:

function Button({
  classes,
  className,
  onClick,
  ...props
}) {
  let [active, setActive] = useState(false);
  let timeoutIds = useRef([]);

    let registerTimeout = (f, ms) => {
    let timeoutId = setTimeout(f, ms);
    timeoutIds.current.push(timeoutId);
  };

  let handleClick = e => {
    e.persist();
    setActive(true);
    if (typeof onClick === "function") onClick(e);
  };

  let cleanup = () => {
    timeoutIds.current.forEach(clearTimeout);
  };

  useEffect(() => {
    if (active === true) {
      registerTimeout(() => setActive(false), 250);
    }
    return cleanup;
  }, [active]);

  return (
    <MuiButton
      variant={finalVariant(variant)}
      className={`${active ? "Mui-active" : ""} ${className}`}
      classes={buttonClasses}
      onClick={handleClick}
      {...props}
    />
  );
}

推荐阅读