Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setTimeout and clearTimeout in reactJS

I am trying to create a greeting UI that fades out before displaying main content.The desired effect can be found HERE

When a certain scroll input, say 100px from the top, is reached

  1. Greeting appears for 5seconds and fades out
  2. Main content waits until greeting fades out and gets displayed.

I achieved this effect with setTimeout but I now want to know how to set clearTimeout properly.

Here is my code

componentDidMount() {
    window.addEventListener(
      "wheel",
      () => requestAnimationFrame(this.handleScroll.bind(this)),
      false
    );
  }

handleScroll(e){  
    const scrolltop = window.scrollY; 
    scrolltop > 120 ? this.showGreeting().bind(this):null
  }

showGreeting(){
    this.setState({
      greetingDisplay:true,
    })
    const timer = setTimeout(this.showContent.bind(this),5000);
  } 

showContent(){

    this.setState({
      greetingDisplay:false,
      contentDisplay:1,
   })
  //How do I clear the timer here? 
}
  • Here is my attempt, Codepen
like image 609
semosem Avatar asked Dec 18 '22 00:12

semosem


2 Answers

In showGreeting,you are setting timeout and storing it in local const varibale.Instead bind it to component instance i.e. this.

constructor(){
     this.timer = null;
      //............rest
  }

showGreeting(){
    this.setState({
      greetingDisplay:true,
    })
    this.timer=setTimeout(this.showContent.bind(this),3000);
    ^^^^^^^^^^^
  } 

When showContent is called state is updated which will trigger render and then componentDidUpdate lifecycle.

In the componentDidUpdate, use this.timer to clear timeout.

componentDidUpdate{
   clearTimeout(this.timer);
}
like image 65
RIYAJ KHAN Avatar answered Dec 31 '22 03:12

RIYAJ KHAN


You can easily use ES6 arrow functions without side effects like this:

showContent = () => {
   this.setState({
      greetingDisplay:false,
      contentDisplay:1,
   }); 
}

showGreeting = () => {
    this.setState({
      greetingDisplay:true,
    });
    setTimeout( () => this.showContent, 3000 );
}
like image 21
Roman Avatar answered Dec 31 '22 02:12

Roman