您如何每分钟触发一次React js组件的重新渲染?

时间:2020-02-28 19:33:53

标签: javascript reactjs components react-hooks

上下文:
定义了一个挂钩,并返回一个对象,该对象包含上次修改文件的时间戳。

我计算从时间戳到现在的时间差,以向用户显示自上次保存以来已经过了多长时间。

const StageFooter = (props) => {
  const [, , meta] = useMetadata("Tenant Setup Data", "setupData")

  return (
    <StageControls>
      <div id="footer-start"></div>
      <SavingBlock key={meta?.modified}>
        {`Last saved ${
          meta.modified !== undefined ? formatDistanceToNow(meta.modified) : " "
        } ago`}
      </SavingBlock>
      <div id="footer-end"></div>
    </StageControls>
  )
}

export default StageFooter


问题:
从时间戳到现在为止的计算出的差不会实时更新。例如,它会说“ Last save 10 minutes ago”,但是经过几分钟后,字符串仍然保持不变。仅当用户离开页面然后返回页面或者用户刷新页面时,它才会更新。

考虑到所有这些,我基本上希望每过一分钟就重新渲染组件,以便实时更新值。

感谢您的时间!

2 个答案:

答案 0 :(得分:2)

您可以创建一种效果,每分钟调用一次setTimeout,并且在显示时间时,只需从日期中减去即可。

您还应该为此创建一个单独的组件,因此,如果在组件内部使用此组件,它将不会重新呈现“每分钟”的孔组件,而只会重新呈现“自上次更改以来的x分钟”文本。

const [fakeCurrentDate, setFakeCurrentDate] = useState(new Date()) // default value can be anything you want

useEffect(() => {
    setTimeout(() => setFakeCurrentDate(new Date()), 60000)
}, [fakeCurrentDate])

...

{/* display time passed since*/}
<div>{fakeCurrentDate - modifiedDate}</div>

工作codesandbox(您需要等待一分钟才能看到更改)

但是,正如斯特林·阿彻(Sterling Archer)在评论中说的那样,这好吗?好吧...谁知道?


建议

另一种解决方法是显示一条消息Updated at XX:XX time,而不是向用户显示已经过去了多少分钟。但这更多的是关于UX而不是技术

答案 1 :(得分:1)

我建议跟踪自从组件的初始安装到当前状态以来经过的时间,并以一定的间隔对其进行更新。然后,我们将考虑初始值显示经过的时间,并加上自接收到初始值以来的经过时间(自组件安装以来)。

export const Time = () => {
    // This would be the initial time. We can get it from a hook
    // (meta.modified in your case) or for this example from a ref.
    // I'm setting this to 2000 meaning it was updated 2 seconds ago.
    const initial_time = useRef(2000);
    const [time_passed, setTimePassed] = useState(0);

    useEffect(() => {
        const interval_time = 1000;

        // Set an interval that will update every interval_time
        const myInterval = setInterval(
            () => setTimePassed(time => time + interval_time),
            interval_time
        );

        // Clear the interval when the component unmounts
        return () => clearInterval(myInterval);
    }, []);

    return initial_time.current + time_passed;
};

为了以友好的方式显示经过的时间,请选中this other question

相关问题