Reputation: 4039
I am trying to access to intervalId "useState" variable inside of a timeInterval function. But the scope is not working properly. intervalId is always null inside ot the timeInterval function, that means that it does not about delay of value assignation.
export function useLocalCommands(length, id) {
const [intervalId, setIntervalId] = useState(null)
const [currentIndex, setCurrentIndex] = useState(10)
const [timeInterval, setTimeInterval] = useState(Constants.READING.READING_TIME_INTERVAL)
let pauseReading = () => {
console.log("pause:" + intervalId)
clearInterval(intervalId)
}
let startReading = () => {
console.log("play")
pauseReading()
if (currentIndex < length) {
setIntervalId(setInterval(() => {
setCurrentIndex((index) => {
if (index < length) {
if (id && index % 40 === 0) {
Meteor.call('myBooks.updateIndex', id, index, (err, res) => {
// show a toast if err
})
}
return index + 1
} else {
console.log("pauseReading: " + intervalId)
pauseReading();
}
})
}, timeInterval))
}
}
}
Thanks you, Best.
Upvotes: 1
Views: 48
Reputation: 281656
IntervalId is being used from closure which is why when the setInterval runs, the values being takes at the time of declaration. However setIntervalId triggeres a state update and even though the value of state is updated, your timerId within setInterval function continues to point to the old state that it used from closure.
Instead of using state, you can make use of useRef to store the timerId. Since refs are mutated, they aren't affected by closure
export function useLocalCommands(length, id) {
const intervalId = useRef(null)
const [currentIndex, setCurrentIndex] = useState(10)
const [timeInterval, setTimeInterval] = useState(Constants.READING.READING_TIME_INTERVAL)
let pauseReading = () => {
console.log("pause:" + intervalId.current)
clearInterval(intervalId.current)
}
let startReading = () => {
console.log("play")
pauseReading()
if (currentIndex < length) {
intervalId.current = setInterval(() => {
setCurrentIndex((index) => {
if (index < length) {
if (id && index % 40 === 0) {
Meteor.call('myBooks.updateIndex', id, index, (err, res) => {
// show a toast if err
})
}
return index + 1
} else {
console.log("pauseReading: " + intervalId.current)
pauseReading();
}
})
}, timeInterval);
}
}
}
Upvotes: 1