Javascript 在创建可以手动更改时间的滴答时钟时遇到问题

Javascript 在创建可以手动更改时间的滴答时钟时遇到问题,javascript,reactjs,Javascript,Reactjs,我正在尝试创建一个时钟,它每秒钟都会滴答作响,但也允许用户单击按钮将时钟向前移动一小时 const addTime=(日期,时间)=>新日期(date.getTime()+时间) 常数时钟=()=>{ const[timeDate,setTimeDate]=useState(addTime(new Date(),SECOND_IN_MS)); 常量updateTimeInfo=(addedTime)=>{ setTimeDate(addTime(timeDate,addedTime); //其他

我正在尝试创建一个时钟,它每秒钟都会滴答作响,但也允许用户单击按钮将时钟向前移动一小时

const addTime=(日期,时间)=>新日期(date.getTime()+时间)
常数时钟=()=>{
const[timeDate,setTimeDate]=useState(addTime(new Date(),SECOND_IN_MS));
常量updateTimeInfo=(addedTime)=>{
setTimeDate(addTime(timeDate,addedTime);
//其他信息省略,不会影响代码
}
useffect(()=>{
让滴答声=设置间隔(()=>{
updateTimeInfo(秒/秒)
},第二名);
返回()=>clearInterval(滴答声);
},[timeDate])
返回(
{timeDate.toLocaleTimeString([],{hour:'2位',hour12:true,minute:'2位'});
updateTimeInfo(小时数)}>{“添加1小时”}
)
}
现在的问题是,每当我将my clock更新为新时间时,就会触发useEffect,时钟将重新建立间隔以每秒钟更新一次,从而导致时钟在1秒过去之前不会更新秒数

我希望时钟总是滴答作响1秒,但也允许用户在同一时间快进1小时


是否有可能做到这一点?

useffect
挂钩中删除
timeDate
依赖项,并在
updateTimeInfo
中使用

  • 安装间隔组件安装时,将清除功能返回到清除间隔

    useEffect(() => {
      const tickClock = setInterval(() => {
        updateTimeInfo(SECOND_IN_MS);
      }, SECOND_IN_MS);
    
      return () => clearInterval(tickClock);
    }, []);
    
  • 功能状态更新允许每个排队的
    timeDate
    状态更新从以前的状态正确更新

    const updateTimeInfo = (addedTime) => {
      setTimeDate((timeDate) => addTime(timeDate, addedTime));
      //other info omitted, won't affect the code
    };
    
  • 工作原理:

    间隔每秒运行一次
    updateTimeInfo
    。该按钮也只是以异步方式调用
    updateTimeInfo
    ,即每当单击+1小时按钮时。这两个按钮应相互独立

    在没有功能状态更新的情况下,只有初始的
    timeDate
    状态值会关闭,并且时间每次只会从初始状态值更新

    代码

    const SECOND_IN_MS=1000;
    常数小时(单位:毫秒)=1000*60*60;
    const addTime=(日期,时间)=>新日期(date.getTime()+时间);
    常数时钟=()=>{
    const[timeDate,setTimeDate]=useState(addTime(new Date(),SECOND_IN_MS));
    常量updateTimeInfo=(addedTime)=>{
    setTimeDate((timeDate)=>addTime(timeDate,addedTime));
    //其他信息省略,不会影响代码
    };
    useffect(()=>{
    常量时钟=设置间隔(()=>{
    updateTimeInfo(第二个);
    },第二名);
    返回()=>clearInterval(滴答声);
    }, []);
    返回(
    {timeDate.TOLOCALITEMESTRING([],{
    小时:“两位数”,
    小时12:是的,
    分钟:“两位数”,
    第二:“两位数”
    })}
    updateTimeInfo(小时/毫秒)}>
    +1小时
    updateTimeInfo(-HOUR\u IN\u MS)}>
    -1小时
    );
    };
    

    Drew,非常感谢。我还没有反应过来,所以我不知道我必须这样做:setTimeDate((timeDate)=>addTime(timeDate,addedTime))。@NoobieProgrammer是的,在我的回答中添加了到的链接。
    const SECOND_IN_MS = 1000;
    const HOUR_IN_MS = 1000 * 60 * 60;
    
    const addTime = (date, time) => new Date(date.getTime() + time);
    
    const Clock = () => {
      const [timeDate, setTimeDate] = useState(addTime(new Date(), SECOND_IN_MS));
    
      const updateTimeInfo = (addedTime) => {
        setTimeDate((timeDate) => addTime(timeDate, addedTime));
        //other info omitted, won't affect the code
      };
    
      useEffect(() => {
        const tickClock = setInterval(() => {
          updateTimeInfo(SECOND_IN_MS);
        }, SECOND_IN_MS);
    
        return () => clearInterval(tickClock);
      }, []);
    
      return (
        <>
          <span>
            {timeDate.toLocaleTimeString([], {
              hour: "2-digit",
              hour12: true,
              minute: "2-digit",
              second: "2-digit"
            })}
          </span>
          <button type="button" onClick={() => updateTimeInfo(HOUR_IN_MS)}>
            +1 hour
          </button>
          <button type="button" onClick={() => updateTimeInfo(-HOUR_IN_MS)}>
            -1 hour
          </button>
        </>
      );
    };