从函数 returns 之后反应状态没有更新
React state not updating after it returns from function
我有一些模拟计时器的代码,它会查看开始时间,将其存储到 localStorage 中并将其与 Date.now() 进行比较,并通过更新递增的状态变量来正确模拟工作计时器每 1 秒在 setInterval 上。即使在页面重新加载后它也能正常工作。
自然地,计时器以毫秒为单位计数,所以我编写了一个将时间格式化为 hours:minutes:seconds 的函数。现在的问题是,计数器在未格式化时实时更新,现在它进入格式化函数,返回的内容格式正确但不会实时递增,我怀疑与函数不相关即使状态每秒递增,也会再次调用。
我的问题是,有没有办法在每次状态发生变化时调用该函数,例如 useEffect?也许是自定义挂钩?
这是我的代码:
const date = new Date()
const [time, setTime] = useState(date.getTime())
//starts timer on button click
function startTimer() {
setStart(true)
localStorage.setItem('startTime', date.getTime())
}
//converts ms time into hours:minutes:seconds
function msToTime(duration) {
let seconds = Math.floor((duration / 1000) % 60),
minutes = Math.floor((duration / (1000 * 60)) % 60),
hours = Math.floor((duration / (1000 * 60 * 60)) % 24)
hours = (hours < 10) ? "0" + hours : hours
minutes = (minutes < 10) ? "0" + minutes : minutes
seconds = (seconds < 10) ? "0" + seconds : seconds
return hours + ":" + minutes + ":" + seconds
}
//the interval that updates time state every second
useEffect(() => {
const timer = setInterval(() => {
setTime(prev => prev+1)
},1000)
return () => {
clearInterval(timer)
}
},[time])
//return the difference between start and time state and formats it
return <h3>{msToTime(Math.abs(+localStorage.getItem('startTime') - time))}</h3>
除了您监督了一个兼容性问题外,您的代码中的一切都很好。在您的 setTime
函数中, prev 参数以毫秒为单位,但您每秒只向其添加一毫秒。将其更改为以下内容:
setTime(prev => prev + 1000)
您还可以使用:
setTime(date.getTime())
我有一些模拟计时器的代码,它会查看开始时间,将其存储到 localStorage 中并将其与 Date.now() 进行比较,并通过更新递增的状态变量来正确模拟工作计时器每 1 秒在 setInterval 上。即使在页面重新加载后它也能正常工作。
自然地,计时器以毫秒为单位计数,所以我编写了一个将时间格式化为 hours:minutes:seconds 的函数。现在的问题是,计数器在未格式化时实时更新,现在它进入格式化函数,返回的内容格式正确但不会实时递增,我怀疑与函数不相关即使状态每秒递增,也会再次调用。
我的问题是,有没有办法在每次状态发生变化时调用该函数,例如 useEffect?也许是自定义挂钩?
这是我的代码:
const date = new Date()
const [time, setTime] = useState(date.getTime())
//starts timer on button click
function startTimer() {
setStart(true)
localStorage.setItem('startTime', date.getTime())
}
//converts ms time into hours:minutes:seconds
function msToTime(duration) {
let seconds = Math.floor((duration / 1000) % 60),
minutes = Math.floor((duration / (1000 * 60)) % 60),
hours = Math.floor((duration / (1000 * 60 * 60)) % 24)
hours = (hours < 10) ? "0" + hours : hours
minutes = (minutes < 10) ? "0" + minutes : minutes
seconds = (seconds < 10) ? "0" + seconds : seconds
return hours + ":" + minutes + ":" + seconds
}
//the interval that updates time state every second
useEffect(() => {
const timer = setInterval(() => {
setTime(prev => prev+1)
},1000)
return () => {
clearInterval(timer)
}
},[time])
//return the difference between start and time state and formats it
return <h3>{msToTime(Math.abs(+localStorage.getItem('startTime') - time))}</h3>
除了您监督了一个兼容性问题外,您的代码中的一切都很好。在您的 setTime
函数中, prev 参数以毫秒为单位,但您每秒只向其添加一毫秒。将其更改为以下内容:
setTime(prev => prev + 1000)
您还可以使用:
setTime(date.getTime())