I have an app that starts an interval when a button is pressed.
I want to stop the interval after a state reaches 5.
I have tried adding the if condition in UseEffect
, and tried putting the condition within the function itself, but both don't seem to work. The console.log(sequence)
does print successfully in useEffect
I can see that the sequence does indeed increase, but it keeps increasing beyond 5 and never clearInterval
.
const [sequence, setSequence] = useState(0)
const interval = () =>{
setInterval(() => {
setSequence((prevSequence) => (
prevSequence 1
))
}, 2000);
}
const plant = ()=>{
interval()
console.log(sequence)
if(sequence>5){
clearInterval (interval)
}
}
useEffect(() => {
console.log(sequence)
if(sequence>5){
return () => clearInterval(interval);
}
}, [sequence]);
return(
<View style = {styles.container} >
<Image
style={{height:500,width:300,}}
source= {tomato[sequence]}
/>
<Button
title = 'Fertilize Plant'
style= {styles.text}
onPress= {plant}>
</Button>
</View>)
}
CodePudding user response:
Issue
You are not clearing the interval correctly.
const interval = () => {
setInterval(() => {
setSequence((prevSequence) => prevSequence 1)
}, 2000);
};
...
useEffect(() => {
console.log(sequence);
if (sequence > 5) {
return () => clearInterval(interval);
}
}, [sequence]);
Here interval
is a reference to the function, not the actual interval timer id returned from setInterval
.
Solution
Store the interval timer id in a React ref to be referenced around the component.
const intervalRef = useRef();
const interval = () => {
intervalRef.current = setInterval(() => {
setSequence((prevSequence) => prevSequence 1)
}, 2000);
};
...
useEffect(() => {
const intervalId = intervalRef.current;
// also clear on component unmount
return () => clearInterval(intervalId);
}, []);
useEffect(() => {
if (sequence > 5) {
clearInterval(intervalRef.current);
}
}, [sequence]);
Also, there's no need to check the sequence
value and clear the interval in the plant
callback, the useEffect
hook with dependency on sequence
will handle that. Plant
only needs to start the interval.
const plant = () => {
interval();
};
CodePudding user response:
You can use the clearInterval
function to stop the interval you had set.
Here is an example;
let counter = 0;
const interval = setInterval(() => {
counter ;
console.log(`Counter = ${counter}`);
if (counter >= 3) {
console.log("Interval Stopped");
clearInterval(interval);
}
}, 1000);