I am trying to clear and setInterval conditionally. However, when I do this, it appears the clearInterval can't see the setInterval.
When I move the clear interval out of the if statement, it works but now can no longer clear the set interval conditionally. What am I missing here?
// Called when user clicks on menu item
const loadQueueStatus = async () => {
// This function will fetch queueStatus data
const queueStatus = async () => {
// eslint-disable-next-line
const queueStatus = await getQueueStatus().then((data) => {
this.setState({queueStatus: data})
});
}
console.log("state is: ", this.state.isVolunteerStatusOpen)
// call the queue right away if the menu just opened, we know if it is opened as state would still say false
// We do this so we don't wait 5 seconds for the first fetch.
if(!this.state.isVolunteerStatusOpen) {
queueStatus()
}
//Set a listener, to pole the data while menu is open
let setListener = setInterval( queueStatus, 5000);
// If the menu is closed, the state will be true, if so, clear the listener
if(this.state.isVolunteerStatusOpen) {
console.log("clearing listener")
clearInterval(setListener);
}
// Extra caution to clear listener
setListener = null
// Inform state of status window status for next click
this.setState({
isVolunteerStatusOpen: !this.state.isVolunteerStatusOpen
})
}
In my code above I was creating a new setInterval function before I cleared it. However, the real issue was that every time setInterval is set, a new ID for that setInterval is created. Even though you store setInterval in a variable, each time you create the setInterval you get a new ID and lose reference to the old one which still exist in memory.
To combat this, at the end of my code where I set state, I pass the variable which is equal to the setInterval to the state. So if the variable equaled 33, this was passed to state. When I clear interval, I reference this ID in state.
// Called when user clicks on menu item
const loadQueueStatus = async () => {
// This function will fetch queueStatus data
const queueStatus = async () => {
// eslint-disable-next-line
const queueStatus = await getQueueStatus().then((data) => {
this.setState({queueStatus: data})
});
}
// call the queue right away if the menu just opened, we know if it is opened as state would still say false
// We do this so we don't wait 5 seconds for the first fetch.
let setIntervalFunction
if(!this.state.isVolunteerStatusOpen) {
queueStatus()
setIntervalFunction = setInterval( queueStatus, 5000);
}
console.log(setIntervalFunction)
//Set a listener, to pole the data while menu is open
// If the menu is closed, the state will be true, if so, clear the listener
if(this.state.isVolunteerStatusOpen) {
console.log("clearing listener")
clearInterval(this.state.setIntervalFunction);
}
// Inform state of status window status for next click
this.setState({
isVolunteerStatusOpen: !this.state.isVolunteerStatusOpen,
setIntervalFunction: setIntervalFunction //Stores reference to setInterval so it can be cleared next time function is called.
})
}