I'm having trouble figuring out why my counter won't reset when I attempt to reset it from a control. I suspect that that I'm making some kind of novice (common and not embarrassing) mistake in how I manipulate state from within my controls.
For example, if I clock "Faster" several times and then click "Normal" counting continues at an accelerated pace: apparently the faster timer has not been cleared by the invocation of startTimer
. Only by subsequently clicking "Reset", or "Stop" followed by "Start" does the faster timer appear to clear. But I'm mystified by why this should be the case: all paths use clearInterval
in the same way.
I suspect that I'm not grasping something general about how state is manipulated in a component; or perhaps how to correctly access a timer from component state.
Why can't I get my timer to clear as expected?
WobblyCounter.tsx:
import React, { useState } from 'react'
import { View, Button, Text } from 'native-base'
import { useDispatch, useSelector } from 'react-redux'
const WobblyCounter = () => {
const [ timerID, setTimerID ] = useState(0)
const [ isRunning, updateIsRunning ] = useState(false)
const [ interval, updateInterval ] = useState(1000)
const count = useSelector((state) => state.count)
const dispatch = useDispatch()
const startTimer = (): void => {
clearInterval(timerID)
setTimerID(setInterval(() => { dispatch( {type: "INCREMENT", step: 1} ) }, interval))
updateIsRunning(true)
}
const stopTimer = (): void => {
clearInterval(timerID)
updateIsRunning(false)
}
return (
<View style={ {paddingTop:50} }>
<Button
onPress={ (): void => { dispatch( {type: "RESET"} ); startTimer() } }>
<Text>Reset</Text>
</Button>
<View style={ {flexDirection: "row"} }>
<Button small bordered dark disabled={ interval <= 250 }
onPress={ (): void => { updateInterval(Math.max(interval - 250, 250)); startTimer() } }>
<Text>Faster</Text>
</Button>
<Button small bordered dark disabled={ interval == 1000 }
onPress={ (): void => { updateInterval(1000); startTimer() } }>
<Text>Normal</Text>
</Button>
<Button small bordered dark
onPress={ (): void => { updateInterval(interval + 250); startTimer() } }>
<Text>Slower</Text>
</Button>
</View>
<Button small style={ Object.assign( {}, {backgroundColor: isRunning ? "red" : "green"} ) }
onPress={ (): void => { isRunning ? stopTimer() : startTimer() } }>
<Text>{isRunning ? "Stop" : "Start"}</Text>
</Button>
<Text>
Debug{"\n"}count = {count}{"\n"}interval = {interval}{"\n"}timerID = {timerID}
</Text>
</View>
)
}
export default WobblyCounter