简体   繁体   English

如何使用 setInterval 构造 useEffect

[英]How to structure useEffect with setInterval

I am missing something obvious but can't see it.我错过了一些明显但看不到的东西。

The updateClock() util runs and populates the markup with the date/time, but only once. updateClock()运行并使用日期/时间填充标记,但只有一次。

I understand that I must create a useEffect and feed in the state variable that changes in order to re-fire the useEffect , but how would I do that in the code below?我知道我必须创建一个useEffect并输入 state 变量,该变量会更改以重新触发useEffect ,但我将如何在下面的代码中执行此操作? Am I setting the interval in the wrong place?我是否将间隔设置在错误的位置? What state variable should be changing every second when the setInterval runs?setInterval运行时,state 变量应该每秒改变一次?

import { updateClock } from '../../utils/updateClock';

interface LaDateTime {
  yr: string;
  mo: string;
  dt: string;
  hrs: string;
  min: string;
  sec: string;
  day: string;
}

export const Network: FunctionalComponent = () => {
  const { language: lang } = useContext(AppContext);
  const [pageContent, setpageContent] = useState<string | undefined>(undefined);
  const [laDate, setLaDate] = useState<LaDateTime | undefined>(undefined);

  /* *********************************************************************** */
  useEffect(() => {
    const currTime = updateClock();
    setLaDate({ yr: currTime[3], mo: currTime[1], dt: currTime[2], hrs: currTime[4], min: currTime[5], sec: currTime[6], day: currTime[0] });
    const interval = window.setInterval(updateClock, 1000);
    // Clear the interval if/when the component is removed from the DOM
    return () => window.clearInterval(interval);
  }, []);
  /* *********************************************************************** */


  return (
    <div class={style.networkDiv}>
      <div class={style.pageData}>
        {pageContent !== undefined && (
          <Typography>
            <div class={style.topStuff}>
              <div class={style.pageContent}>
                <Markup markup={pageContent} trim={false} type='html' />
              </div>
              <div class={style.clockDiv}>
                <div class={style.timedate}>
                  <a id='day'>{laDate?.day}</a>
                  <br />
                  <a id='mon'>{laDate?.mo}</a>
                  <a id='d'>{laDate?.dt}</a>,<a id='y'>{laDate?.yr}</a>
                  <br />
                  <a id='h'>{laDate?.hrs}</a> :<a id='m'>{laDate?.min}</a>:<a id='s'>{laDate?.sec}</a>
                </div>
              </div>
            </div>

You need to update the state (call setLaDate ) inside the setInterval callback, which is what will trigger a re-render of your component.您需要在setInterval回调中更新 state (调用setLaDate ),这将触发组件的重新渲染。

Simply change:简单地改变:

useEffect(() => {
  const currTime = updateClock();

  // This is only called one time when the component is mounted. The state
  // is not updated later on each clock update, so your component is not
  // re-rendering:
  setLaDate({
    yr: currTime[3],
    mo: currTime[1],
    dt: currTime[2],
    hrs: currTime[4],
    min: currTime[5],
    sec: currTime[6],
    day: currTime[0],
  });

  // ...despite updateClock being called every second:
  const interval = window.setInterval(updateClock, 1000);

  return () => window.clearInterval(interval);
}, []);

To:至:

useEffect(() => {
  function tick() {
    const currTime = updateClock();

    // Now you update the state every second as well, which triggers a re-render:
    setLaDate({
      yr: currTime[3],
      mo: currTime[1],
      dt: currTime[2],
      hrs: currTime[4],
      min: currTime[5],
      sec: currTime[6],
      day: currTime[0],
    });
  } 

  tick();

  const interval = window.setInterval(tick, 1000);

  return () => window.clearInterval(interval);
}, []);

Additionally, I would probably create an useInterval hook to be able to use setInterval declaratively, as explained here: https://stackoverflow.com/a/59274004/3723993此外,我可能会创建一个useInterval挂钩,以便能够以声明方式使用setInterval ,如下所述: https://stackoverflow.com/a/59274004/3723993

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

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