setInterval 启动和停止行为
setInterval start and stop behavior
我正在创建一个秒表,它有一个按钮来开始和停止时间,但我在设置间隔行为方面遇到了问题。
当在 React 的功能组件级别声明时,它将 运行 一旦挂载。
示例:
const Timer = () => {
const timer = setInterval(() => console.log('running'), 1000)
}
当我在函数中声明它时,它不会运行直到函数被调用,但我无法让它停止。
const Timer = () => {
const [start, setStart] = useState(false)
const startStopTimer = () => {
const timer = setInterval(() => console.log('running'), 1000)
}
return (<Button
onClick={() => {
setStarted(!start)
startStopTimer()
}
> Start/Stop </Button>)
}
然后我尝试在函数中添加 clearInterval()
并在 start === false
时有条件地调用它。在这个实现中,第一次点击按钮什么都不做。第二次点击启动计时器,但无法停止。
const Timer = () => {
const [start, setStart] = useState(false)
const startStopTimer = () => {
let timer = setInterval(() => console.log('running'), 1000)
if (!started) clearInterval(timer)
}
return (<Button
onClick={() => {
setStarted(!start)
startStopTimer()
}
> Start/Stop </Button>)
}
再见,我建议你这样修改你的代码:
const Timer = () => {
//const [start, setStart] = useState(false) do not use state for scripting reasons
let timer = null;
const startStopTimer = () => {
if(!timer) timer = setInterval(() => console.log('running'), 1000)
else {
clearInterval(timer)
timer = null
}
}
return (<Button
onClick={() => {
//setStarted(!start)
startStopTimer()
}
> Start/Stop </Button>)
}
说明:timer
应该定义在 startStopTimer
之外,否则,每次启动 startStopTimer
时,都会创建一个新的 timer
。
好的,这很简单,但现在是重要的部分:我强烈建议您不要出于脚本原因使用 React 状态。反应状态应该只用于渲染原因。为什么?因为钩子是异步的,如果你在使用 setStart
后立即读取 start
,你将读取一个旧值。
timer
变量是本地变量,每次调用 sartStopTimer()
时仅在 sartStopTimer()
范围内,它会生成新的 timer
并且在清除超时时,您只会清除最近生成的一个不是以前的 timer
let timer;
const startStopTimer = () => {
timer = setInterval(() => console.log('running'), 1000)
if (!started) clearInterval(timer)
}
创建 timer
全局变量。
这应该可以帮助您入门。
试试这个:
const Timer = () => {
const [timerId, setTimerId] = useState(null)
function startStopTimer(){
if (timerId) {
clearInterval(timerId)
setTimerId(null)
} else {
setTimerId(setInterval(() => console.log('hello'), 1000))
}
}
return <button onClick={startStopTimer}> Start/Stop </button>
}
顺便说一句,不需要使用状态。如果你不需要保持定时器状态,你当然可以使用普通变量。
我正在创建一个秒表,它有一个按钮来开始和停止时间,但我在设置间隔行为方面遇到了问题。
当在 React 的功能组件级别声明时,它将 运行 一旦挂载。
示例:
const Timer = () => {
const timer = setInterval(() => console.log('running'), 1000)
}
当我在函数中声明它时,它不会运行直到函数被调用,但我无法让它停止。
const Timer = () => {
const [start, setStart] = useState(false)
const startStopTimer = () => {
const timer = setInterval(() => console.log('running'), 1000)
}
return (<Button
onClick={() => {
setStarted(!start)
startStopTimer()
}
> Start/Stop </Button>)
}
然后我尝试在函数中添加 clearInterval()
并在 start === false
时有条件地调用它。在这个实现中,第一次点击按钮什么都不做。第二次点击启动计时器,但无法停止。
const Timer = () => {
const [start, setStart] = useState(false)
const startStopTimer = () => {
let timer = setInterval(() => console.log('running'), 1000)
if (!started) clearInterval(timer)
}
return (<Button
onClick={() => {
setStarted(!start)
startStopTimer()
}
> Start/Stop </Button>)
}
再见,我建议你这样修改你的代码:
const Timer = () => {
//const [start, setStart] = useState(false) do not use state for scripting reasons
let timer = null;
const startStopTimer = () => {
if(!timer) timer = setInterval(() => console.log('running'), 1000)
else {
clearInterval(timer)
timer = null
}
}
return (<Button
onClick={() => {
//setStarted(!start)
startStopTimer()
}
> Start/Stop </Button>)
}
说明:timer
应该定义在 startStopTimer
之外,否则,每次启动 startStopTimer
时,都会创建一个新的 timer
。
好的,这很简单,但现在是重要的部分:我强烈建议您不要出于脚本原因使用 React 状态。反应状态应该只用于渲染原因。为什么?因为钩子是异步的,如果你在使用 setStart
后立即读取 start
,你将读取一个旧值。
timer
变量是本地变量,每次调用 sartStopTimer()
时仅在 sartStopTimer()
范围内,它会生成新的 timer
并且在清除超时时,您只会清除最近生成的一个不是以前的 timer
let timer;
const startStopTimer = () => {
timer = setInterval(() => console.log('running'), 1000)
if (!started) clearInterval(timer)
}
创建 timer
全局变量。
这应该可以帮助您入门。
试试这个:
const Timer = () => {
const [timerId, setTimerId] = useState(null)
function startStopTimer(){
if (timerId) {
clearInterval(timerId)
setTimerId(null)
} else {
setTimerId(setInterval(() => console.log('hello'), 1000))
}
}
return <button onClick={startStopTimer}> Start/Stop </button>
}
顺便说一句,不需要使用状态。如果你不需要保持定时器状态,你当然可以使用普通变量。