在所有页面中运行setInterval react js



我想在我的web应用程序中计时模块,当用户点击启动时,它将运行,直到用户停止。这是我的代码

useEffect(() => {
let secondsInterval = () => {};
if (clockRunning) {
secondsInterval = setInterval(() => {
localStorage.setItem("seconds", seconds+1);
setseconds((prev) => prev + 1);
if (seconds == 59) {
localStorage.setItem("minutes", minutes+1);
setminutes((prev) => prev + 1);
setseconds(0);
if (minutes == 59) {
localStorage.setItem("hours", hours+1);
setminutes(0);
sethours((prev) => prev + 1);
}
}
}, 1000);
}
return () => clearInterval(secondsInterval);
}, [seconds, clockRunning]);

如果我删除clearInterval,它在interval中会像匿名运行一样受到干扰。我如何运行这个setinterval,即使组件将卸载i:e更改路由。我使用的是react路由器dom。感谢

您不能在组件卸载时运行它,因为这违反了React的基本原则。钩子和与之相关的一切都是";拥有";通过该组件,当它被卸载时,所有的东西都会被设计清理掉。不清除间隔将是一个错误,因为您将调用不存在的setter。

答案是将状态/挂钩提升到更高的组件,如应用程序根,然后通过上下文或其他方式传递数据。

在新文件中,TimerContext:

import { createContext } from 'react'
export const TimerContext = createContext({
seconds: 0,
minutes: 0,
hours: 0,
pauseClock: () => throw new Error('Must be called in context')
})

在新文件TimerProvider:中

import { useState, useEffect, useCallback } from 'react'
import { TimerContext } from './TimerContext'
export const TimerProvider = ({children}) => {
const [seconds, setSeconds] = useState(localStorage.getItem('seconds') ?? 0)
const [minutes, setMinutes] = useState(localStorage.getItem('minutes') ?? 0)
const [hours, setHours] = useState(localStorage.getItem('hours') ?? 0)
const [clockRunning, setClockRunning] = useState(0)
const pauseClock = useCallback((run) => setClockRunning(run), [])
useEffect(() => {
let secondsInterval;
if (clockRunning) {
secondsInterval = setInterval(() => {
localStorage.setItem("seconds", seconds+1);
setseconds((prev) => prev + 1);
if (seconds == 59) {
localStorage.setItem("minutes", minutes+1);
setminutes((prev) => prev + 1);
setseconds(0);
if (minutes == 59) {
localStorage.setItem("hours", hours+1);
setminutes(0);
sethours((prev) => prev + 1);
}
}
}, 1000);
}
return () => secondsInterval && clearInterval(secondsInterval);
}, [clockRunning]);
return <TimerContext.Provider value={{ seconds, minutes, hours, 
pauseClock}}> 
{children}
</TimerContext.Provider>
}

在你的一个高级组件,如应用程序或其他东西:

import { TimerProvider } from './TimerProvider'
// existing stuff
const App = () => {
// Existing stuff
return <TimerProvider>
{/* Your existing app contents here */}
</TimerProvider>
}

无论您需要在哪里获取数据:

import { useContext } from 'react'
import { TimerContext } from './TimerContext'
const Consumer = () => {
const { seconds, minutes, hours, pauseClock } = useContext(TimerContext)
}

最新更新