Reputation: 745
I created a function, when user click start button that function and timer will start. However, when time reach 60 I want to call stop function but can't figure out how to that. can someone tell me how to do that please.
const [time,setTime] = useState(0)
const timeout = useRef()
const onStart = () => {
timeout.current = setInterval(() => {
if (time != 60) {
setTime(prevState => prevState + 1);
if (time == 60) {
onStop()
}
}
}, 1000);
}
const onStop = () => {
clearInterval(timeout.current);
}
Upvotes: 1
Views: 305
Reputation: 8316
If you don't have to use time
in your JSX, then consider converting it to ref
. There are certainly closure issues which will take place where the value of time
state that you expect to be isn't what it will be. Your logic problem of correctly using if
statements is also covered here.
const time = useRef(0)
const timeout = useRef()
const onStart = () => {
timeout.current = setInterval(() => {
if (time.current != 60) {
time.current+=1;
}
if (time.current == 60) {
onStop()
}
}, 1000);
}
const onStop = () => {
clearInterval(timeout.current);
}
And in case you need a state
to be used in JSX, just make one timer
as ref and time
as state like so :-
const timer = useRef(0)
const [time,setTime] = useState(0);
const timeout = useRef()
const onStart = () => {
timeout.current = setInterval(() => {
if (timer.current != 60) {
setTime(prevState => prevState + 1);
timer.current+=1;
}
if (timer.current == 60) {
onStop()
}
}, 1000);
}
const onStop = () => {
clearInterval(timeout.current);
}
See this codesandbox example doing what you want :-
Here is another React
way which is much less code and confusion :-
const [time, setTime] = useState(0);
const timeout = useRef();
useEffect(() => {
onStart();
}, []);
useEffect(() => {
if (time === 60) {
onStop();
}
}, [time]);
const onStart = () => {
timeout.current = setInterval(() => {
setTime((prevState) => prevState + 1);
}, 1000);
};
const onStop = () => {
clearInterval(timeout.current);
};
Upvotes: 1
Reputation: 277
From the looks of it. Your code will never stop at 60. As the if statement if (time != 60)
only runs the code if the time IS NOT 60. Then within that if statement, you've got another if statement going if time is 60
which it CAN'T be within that if statement as that code is only executed when time does not equal 60
Change
const [time,setTime] = useState(0)
const timeout = useRef()
const onStart = () => {
timeout.current = setInterval(() => {
if (time != 60) {
setTime(prevState => prevState + 1);
if (time == 60) {
onStop()
}
}
}, 1000);
}
const onStop = () => {
clearInterval(timeout.current);
}
to
const [time,setTime] = useState(0)
const timeout = useRef()
const onStart = () => {
timeout.current = setInterval(() => {
if (time != 60) {
setTime(prevState => prevState + 1);
}
if (time === 60) {
onStop();
}
}, 1000);
}
const onStop = () => {
clearInterval(timeout.current);
}
Upvotes: 0
Reputation: 77
You are first checking if time != 60 this means when its 60 it will not enter in the statement and will not reach the second statement. I think you have to do it like this:
timeout.current = setInterval(() => {
if (time == 60) {
onStop()
}
setTime(prevState => prevState + 1);
}, 1000);
Upvotes: 0