Reputation: 322
I'm following a beginner's tutorial for the useState and useRef hooks, trying to implement a simple timer in react.
I'm using the interval
variable to store the value from setInterval()
On click of start button, I am able to console.log the value of the interval correctly.
However on click of stop button, interval.current
is console logged as undefined
. The stopTimer()
hence does not function as expected.
Why does interval.current print undefined when it is clearly set in startTimer (and logged there)? What am I missing here?
import React, { useState, useRef } from 'react';
const pad = (time) => {
return time.toString().padStart(2, "0");
};
function App() {
const [title, setTitle] = useState("Pomodoro!");
const [timeLeft, setTimeLeft] = useState(5);
const interval = useRef(null);
const startTimer = () => {
interval.current = setInterval(() => {
setTimeLeft((timeLeft) => {
if (timeLeft >= 1) {
return timeLeft - 1;
}
return 0;
});
}, 1000);
console.log(interval.current, " :in start");
}
const stopTimer = (interval) => {
console.log("in stop: ", interval.current);
clearInterval(interval.current);
}
const resetTimer = () => { }
const minutes = pad(Math.floor(timeLeft / 60));
const seconds = pad((timeLeft - minutes * 60));
return (
<div>
<div>{title}</div>
<div>
<span>{minutes}</span>
<span>:</span>
<span>{seconds}</span>
</div>
<div>
<button onClick={startTimer}>Start</button>
<button onClick={stopTimer}>Stop</button>
<button onClick={resetTimer}>Reset</button>
</div>
</div>
);
}
export default App;
output in console
6 " :in start" in stop: undefined
Thanks
Upvotes: 1
Views: 3218
Reputation: 3053
I believe it is because you pass a lower scope variable called interval
to stopTimer
, but when you call stopTimer
you do not pass the argument, so it is undefined when you're accessing it.
You probably referring to interval
you've defined as ref
so you need to just access it without passing interval
to stopTimer
, try this:
const stopTimer = () => {
console.log("in stop: ", interval.current);
clearInterval(interval.current);
}
Upvotes: 2
Reputation: 339
Considering what your code is doing, I believe interval
should be a state variable and not a ref. That is to say, you should use
const [interval, setInterval] = useState(null);
instead of const interval = useRef(null);
Refs are used to be linked to DOM elements (for instance a form element you wish to refer to when a button is clicked). It's only when a ref variable is correctly referencing a DOM element that their current
attribute is defined.
Upvotes: 0