Reputation: 331
In single page web app, city's map rendered with traffic layer.
Currently, working on a live mode switch, which if ON should update the traffic layer on map every 5 minutes.
When live mode is switched off, the 5 minute timer should go off.
For this requirement, got hints for two options from few blogs & posts.
1. Javascript methods: setInterval and clearInterval
2. Use of web sockets
Since this web app has only couple of users besides lack of knowledge for web sockets, decided to go with the first option.
However, faced difficulty in successful execution of clearInterval() when switch goes to off mode.
In the code below, 'timeout' value passed to clearInterval is always undefined.
const handleOkBtnClick = (): void => {
let timeout;
if(live){
timeout = setInterval(updateFilter, 60000);
console.log('live ON == '+ timeout); // prints number like 89 or 146
}else{
console.log('live Off == '+ timeout); //always prints 'undefined'
clearInterval(timeout);
}
}
}
It looks like conditional execution of setInterval and clearInterval isn't an option.
Jumping in to javascript development after a decade, What am I missing?
Any suggestion for alternative approach will be appriciated.
Using ReactJS v16.11, Typescript v3.7
Upvotes: 0
Views: 2752
Reputation: 281874
The issue here is that timeout
variable is defined within handleOkBtnClick
so whenever this function is called, the timeout value is reset to undefined and if live is true, its set to timerId
The solution here is to move the timer to a class variable
class TrafficLights extends React.Component {
timeout = null
...
handleOkBtnClick = (): void => {
if(live){
this.timeout = setInterval(updateFilter, 60000);
console.log('live ON == '+ this.timeout); // prints number like 89 or 146
}else{
console.log('live Off == '+ this.timeout);
clearInterval(this.timeout);
}
}
}
...
}
Now it looks like you use functional component, so you can store the timeout in a useRef
if you use react-hooks
const TrafficLights = () => {
const timeout = useRef<number | null>(null);
...
const handleOkBtnClick = (): void => {
if(live){
timeout.current = window.setInterval(updateFilter, 60000);
console.log('live ON == '+ timeout.current); // prints number like 89 or 146
}else{
console.log('live Off == '+ timeout.current);
clearInterval(timeout.current);
}
}
}
...
}
Upvotes: 2
Reputation: 331
const [timeout, setTimeout] = useState(0);
const handleOkBtnClick = (): void => {
if(live){
setTimeout(window.setInterval(updateFilter, 60000));
console.log('timeout == '+ timeout);
}else{
console.log('clearInterval == '+ timeout);
clearInterval(timeout);
}
}
This code is working without any warning or error.
But, pros and cons of using window.setInterval Vs. setInterval if any, should be taken into consideration.
Upvotes: 0