我无法在React Native组件中获取按钮以根据计时器是否正在运行来更改状态。我已将状态添加到我的组件中,以便在启动和停止计时器时进行切换,但是在停止计时器后进行切换时,计时器会继续运行(或永不停止)。神秘地(至少对于这个新手而言),如果我注释掉计时器停止时切换状态的那一行,计时器就可以正常工作。
也许我只是完全采用了错误的方法。
如何使组件中的元素响应我的计时器当前是否正在运行?
SillyCounter.tsx :
import React, { useEffect, useState } from 'react'
import { View, Button, Text } from 'native-base'
const SillyCounter = () => {
let timerID = 0
const [ isRunning, updateIsRunning ] = useState(false)
const startTimer = (): void => {
clearInterval(timerID)
timerID = setInterval(() => { /* ... */ }, 1000)
updateIsRunning(true)
}
const stopTimer = (): void => {
clearInterval(timerID)
updateIsRunning(false) // Starts timer again! Comment out and timer stops as expected; why?
}
useEffect(() => {
startTimer()
return () => { stopTimer() }
} )
return (
<View>
<View style={ {flexDirection: "row"} }>
<Button small transparent success onPress={ (): void => { startTimer() } }>
<Text> </Text>
</Button>
<Button small transparent danger onPress={ (): void => { stopTimer() } }>
<Text> </Text>
</Button>
</View>
<Button small style={ Object.assign({},
{backgroundColor: isRunning ? "red" : "green"} ) } >
<Text>{isRunning ? "+" : "-"}</Text>
</Button>
</View>
)
}
export default SillyCounter
答案 0 :(得分:3)
这是由于useEffect
造成的。
每次更改状态时,默认情况下都会执行useEffect
。
因此,当您单击按钮以stopTimer
时,它会使用updateIsRunning(false)
来更改状态,因为状态更改时,您的useEffect
被执行,结果startTimer
被执行,这将启动计时器再次。
注释updateIsRunning(false)
时,状态不会改变,useEffect
将不会执行。最后,您的计时器停止计时。
就您而言,您根本不需要useEffect
。您可以删除它。但是如果您的计时器正在运行并且不小心导航到其他组件,则需要清理计时器,
useEffect(() => {
return () => { clearInterval(timerID) }
}, [])
或者,如果您希望计时器在默认情况下首次安装组件时启动,则需要为useEffect
提供第二个参数(空数组),
useEffect(() => {
startTimer()
return () => {
// Don't call `stopTimer()` here, it will give you the warning that cannot set state on unmounted component.
// The `clearInterval(timerID)` will do the work, because on component re-mount it will always starts with initial values.
clearInterval(timerID)
}
}, []) //Now useEffect executes only once when component mounts and not for sub-sequent re-renders
要了解有关second argument
的更多信息,请查看this中的Optimizing Performance by Skipping Effects
部分。