useEffect 不运行命名的 setInterval

问题描述 投票:0回答:1

我有一个接受 $nextUpdateDatTime 的组件(组件应更新的时间和日期)。 useEffect 不想运行 setInterval 或 setTimeout。如果我删除名称 setTimeout(或 setInterval),它会触发,但只会触发一次,之后就不会触发。我尝试将此功能移至父组件并通过 props 传输秒数 - 结果完全相同。但是,如果我更改组件代码中的某些内容并保存它(例如,添加 console.log),那么计时器就会开始工作!但是一旦我刷新页面,useEffect就看不到并且不会再次运行setInterval(setTimeout)。

代码:

interface IMinutesRemainingProps {
    $nextUpdateDateTime: string;
}

function MinutesRemaining({
    $nextUpdateDateTime}: IMinutesRemainingProps) {

    const [secondsToUpdate, setSecondsToUpdate] = useState(0);
    
    const changeMinutesToUpdate = () => {
        const currentDateTime = new Date().getTime();
        const nextUpdate = new Date($nextUpdateDateTime).getTime();
        
        setSecondsToUpdate(Math.round((nextUpdate - currentDateTime) / (1000)));
    }

    useEffect(() => {
        console.log('mount')
        const updateRespawnInterval = setInterval(() => {
            console.log('interval')
            changeMinutesToUpdate();
        }, 1000);
        
        return () => {
            console.log('unmount')
            clearInterval(updateRespawnInterval);
        }
    }, [secondsToUpdate])

    return (
        <Minutes>
            ⟳ {secondsToUpdate}s
        </Minutes>
    );
}

控制台日志: 山 卸载 安装

我尝试删除返回,我尝试删除依赖项数组或将其留空。我还尝试将所有功能移至父组件并通过 props 传输秒数 - 这些都没有帮助。

reactjs settimeout setinterval
1个回答
0
投票

您的组件:

import { useState, useEffect } from "react";

interface IMinutesRemainingProps {
  nextUpdateDateTime: string;
}

function MinutesRemaining({ nextUpdateDateTime }: IMinutesRemainingProps) {
  const [secondsToUpdate, setSecondsToUpdate] = useState<number>(() => {
    const currentDateTime = new Date().getTime();
    const nextUpdate = new Date(nextUpdateDateTime).getTime();
    return Math.round((nextUpdate - currentDateTime) / 1000);
  });

  useEffect(() => {
    const updateRespawnInterval = setInterval(() => {
      changeMinutesToUpdate();
    }, 1000);

    return () => {
      clearInterval(updateRespawnInterval);
    };
  }, []);

  const changeMinutesToUpdate = () => {
    setSecondsToUpdate((prevSeconds) => {
      if (prevSeconds > 0) {
        return prevSeconds - 1;
      } else {
        return 0;
      }
    });
  };

  return <div>⟳ {secondsToUpdate}s</div>;
}

export default MinutesRemaining;

设置属性:

<MinutesRemaining nextUpdateDateTime="2024-01-22T12:00:00" />
© www.soinside.com 2019 - 2024. All rights reserved.