Reputation: 61
I am using 3 dynamic variable inside setInterval, in state
this.state={
checked: true,
currentHash:"some current hash",
updating: true
}
inside componentDidMount, i've done something like this
componentDidMount = () => {
let timer
timer = setInterval( (checked, currentHash, updating) => {
try {
this.setState({analysis:true});
if(checked){
var generatedHash = "current generated hash";
if (currentHash !== generatedHash) {
currentHash = generatedHash;
if(updating){
this.setState({updating:false})
const updateResponse = this.props.sendFile(DOCUMENT_ANALYSIS, ""); // my api call
}
else{
this.setState({analysis:false})
}
}
else{
this.setState({analysis:false})
}
clearInterval(timer);
this.componentDidMount();
}
else{
clearInterval(timer);
this.setState({analysis:false});
this.componentDidMount();
}
}
catch (error) {
console.log("Event error", error);
}
}, 10000, this.state.checked, this.state.currentHash, this.state.updating)
}
The interval is set to 10 seconds. But before getting correct state data, it is calling the same function twice.
Upvotes: 4
Views: 149
Reputation: 16
I believe the timer
variable should be accessable to the whole component instead of the function.
Whats happening is, since the timer
variable is only scoped to the running block, the clearInterval
never clears it, but the timer is already set, so the rendering happens again.
Upvotes: 0
Reputation: 105
From the docs of ReactJS:
You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues. In most cases, you should be able to assign the initial state in the constructor() instead. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.
It appears that setInterval may be calling setState immediately.
Upvotes: 0
Reputation: 1
you can try this or you can try react hook can be better
componentDidMount =()=> {
this.time();
}
time =()=>{
let timer
timer = setInterval( (checked, currentHash, updating) => {
try {
this.setState({analysis:true});
if(checked){
var generatedHash = "current generated hash";
if (currentHash !== generatedHash) {
currentHash = generatedHash;
if(updating){
this.setState({updating:false})
const updateResponse = this.props.sendFile(DOCUMENT_ANALYSIS, ""); // my api call
}
else{
this.setState({analysis:false})
}
}
else{
this.setState({analysis:false})
}
clearInterval(timer);
this.componentDidMount();
}
else{
clearInterval(timer);
this.setState({analysis:false});
this.componentDidMount();
}
}
catch (error) {
console.log("Event error", error);
}
}, 10000, this.state.checked, this.state.currentHash, this.state.updating)
}
Upvotes: 0