简体   繁体   English

如何清理 function 在 useEffect 之外?

[英]How to clean up function that is outside useEffect?

I have a resend code button and will disable it for 30sec after pressed.我有一个重新发送代码按钮,按下后将禁用它 30 秒。 Here is my function.这是我的 function。

    const time = useRef(30);

    function disableResendBtn() {
        time.current = 30;
        setsendCodeBtnDisabled(true);
        const interval = setInterval(() => {
            (time.current = time.current - 1),
                setsendCodeBtnText(i18n.t('RESEND') + '(' + time.current + ')'),
                console.log(time.current);
        }, 1000);
        setTimeout(() => {
            setsendCodeBtnDisabled(false);
            setsendCodeBtnText(i18n.t('RESEND'));
            clearInterval(interval);
        }, 30000);
    }

I am getting a error of 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 %s.%s, a useEffect cleanup function我收到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 %s.%s, a useEffect cleanup function 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 %s.%s, a useEffect cleanup function 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 %s.%s, a useEffect cleanup function when I move on to next page. 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 %s.%s, a useEffect cleanup function This error is not showing everytime.此错误并非每次都显示。 So I am confused whether setInterval/setTimeout function is the reason.所以我很困惑是否是 setInterval/setTimeout function 的原因。

Anyway, how I can use the useEffect to clean up that?无论如何,我如何使用 useEffect 来清理它? The function is not inside useEffect. function 不在 useEffect 中。

You can store the setInterval 's and setTimeout 's return value in a ref and then create an empty useEffect which will then clean up those for you.您可以将setIntervalsetTimeout的返回值存储在 ref 中,然后创建一个空的useEffect ,它会为您清理这些值。

There is a simpler way that I can think of.我能想到一种更简单的方法。 Instead of tracking these intervals and timeouts and then cleaning up using an empty useEffect , you can just create a useEffect which updates the current time every second.无需跟踪这些间隔和超时,然后使用空的useEffect进行清理,您只需创建一个每秒更新当前时间的useEffect And, to track the disabled state, you can create another state which tracks "until when the button should be disabled".并且,要跟踪禁用的 state,您可以创建另一个 state 来跟踪“直到应该禁用按钮”。

export default function App() {
  const [currentTime, setCurrentTime] = React.useState(Date.now());
  const [disabledUntil, setDisabledUntil] = React.useState(0);

  React.useEffect(() => {
    const interval = setInterval(() => {
      setCurrentTime(Date.now());
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  const onClick = () => {
    // disable button for 30 seconds
    setDisabledUntil(Date.now() + 30 * 1000);
  };

  const buttonDisabledSeconds = Math.floor(
    (disabledUntil - currentTime) / 1000
  );

  return (
    <div>
      <button onClick={onClick} disabled={currentTime < disabledUntil}>
        Send
      </button>
      <p>
        {buttonDisabledSeconds >= 0 &&
          `Button disabled for ${buttonDisabledSeconds} seconds`}
      </p>
    </div>
  );
}

This way, the cleanup is very close to the actual interval definition.这样, cleanup非常接近实际的间隔定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM