更新日期现在在React钩子



我需要创建一个自定义钩子来更新点击

时的当前时间
export const useNow = (): [number, VoidFunction] => {
const [now, setNow] = React.useState(Date.now())
const update = () => {
const newDate = new Date(now)
setNow(Date.parse(newDate.getTime().toString()))
}
return [now, update]
}

问题是无论何时调用update方法,now状态总是用相同的值更新。

如何用当前时间戳正确设置now?

另外,请注意您可以使用setInterval自动更新:

function useNow(refreshFrequency: number): Date {
const [now, setNow] = useState(new Date);
useEffect(() => {
const interval = setInterval(
() => setNow(new Date()),
refreshFrequency,
);
return () => clearInterval(interval);
});
return now;
}

你可以简单地在组件中使用const now = useNow();

now不更新的原因是new Date(now)创建了一个新的日期实例,其默认状态为Date.now(),该状态已在组件的顶部提供。

在更新期间创建new Date()应该可以解决您的问题。

import React from "react";
export const useNow = (): [number, VoidFunction] => {
const [now, setNow] = React.useState<number>(new Date().getTime());
const update = () => {
setNow(new Date().getTime());
};
return [now, update];
};

受他的回答的启发,我采取了稍微不同的方法。

钩子不再更新每一个x刻度,下面的代码允许钩子在时间改变了x个单位时更新。

这两种不同方法之间的区别在某些情况下是有用的,例如,如果您正在显示时钟,并希望稍微准确地反映当前时间。

type UnitOfTime = "year" | "month" | "date" | "hour" | "minute" | "second" | "millisecond";
function getDatePart(date: Date, part: UnitOfTime) {
switch (part) {
case "year":
return date.getFullYear();
case "month":
return date.getMonth();
case "date":
return date.getDate();
case "hour":
return date.getHours();
case "minute":
return date.getMinutes();
case "second":
return date.getSeconds();
case "millisecond":
return date.getMilliseconds();
}
}
function useNow(frequency: number, unit: UnitOfTime) {
const [now, setNow] = useState(new Date());
useEffect(() => {
const interval = setInterval(() => {
const newNow = new Date();
const diff = Math.abs(getDatePart(newNow, unit) - getDatePart(now, unit));
if (diff >= frequency) {
setNow(newNow);
}
}, 1);
return () => clearInterval(interval);
});
return now;
}

与链接答案的区别示例:

考虑你的钩子在11:59被调用,你希望它每小时更新一次。对于链接的答案,钩子将在12:59更新时间,而此解决方案将在12:00更新时间。


免责声明:

  • 每隔一秒运行一个setInterval可能会有负面影响,但从我有限的测试中,它似乎工作得很好,没有明显的性能影响。
  • 我对此做了最少的测试,但它似乎按预期工作