React Native 如何清除useEffect之外的函数?

wz8daaqr  于 2022-11-17  发布在  React
关注(0)|答案(1)|浏览(156)

我有一个重新发送代码按钮,按下后将禁用它30秒。这里是我的功能。

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

当我进入下一页时,我得到一个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的错误。这个错误不是每次都显示。所以我不知道setInterval/setTimeout函数是否是原因。
无论如何,我如何才能使用useEffect来清理它呢?函数不在useEffect内部。

xzv2uavs

xzv2uavs1#

您可以将setIntervalsetTimeout的返回值存储在一个ref中,然后创建一个空的useEffect,它将为您清除这些值。
我想到了一个更简单的方法。不用跟踪这些时间间隔和超时,然后使用空的useEffect进行清理,您可以创建一个useEffect,它每秒更新当前时间。而且,为了跟踪禁用状态,您可以创建另一个状态,它跟踪“直到按钮应该被禁用的时间”。

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

这样,cleanup就非常接近于实际的间隔定义。

相关问题