126

In react.js, is it better to store a timeout reference as an instance variable (this.timeout) or a state variable (this.state.timeout)?

React.createClass({
     handleEnter: function () {
         // Open a new one after a delay
         var self = this;
         this.timeout = setTimeout(function () {
             self.openWidget();
         }, DELAY);
     },
     handleLeave: function () {
        // Clear the timeout for opening the widget
        clearTimeout(this.timeout); 
     }
    ...
})

or

React.createClass({
     handleEnter: function () {
         // Open a new one after a delay
         var self = this;
         this.state.timeout = setTimeout(function () {
             self.openWidget();
         }, DELAY);
     },
     handleLeave: function () {
        // Clear the timeout for opening the widget
        clearTimeout(this.state.timeout); 
     }
    ...
})

both of these approaches work. I just want to know the reasons for using one over the other.

3
  • 13
    From the documentation: "NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable." Commented Aug 8, 2014 at 16:12
  • 6
    Tip: Use React’s autobinding: this.timeout = setTimeout(this.openWidget, DELAY); Commented Aug 8, 2014 at 21:05
  • 1
    What should DELAY be set to? Commented Dec 15, 2014 at 19:39

2 Answers 2

176

I suggest storing it on the instance but not in its state. Whenever state is updated (which should only be done by setState as suggested in a comment), React calls render and makes any necessary changes to the real DOM.

Because the value of timeout has no effect on the rendering of your component, it shouldn't live in state. Putting it there would cause unnecessary calls to render.

Sign up to request clarification or add additional context in comments.

Comments

12

In addition to what @ssorallen said, you should also remember to handle the component unmounting before your handleLeave is called.

React.createClass({
     handleEnter: function () {
         // Open a new one after a delay
         this._timeout = setTimeout(function () {
             this.openWidget();
         }.bind(this), DELAY);
     },
     handleLeave: function () {
        // Clear the timeout for opening the widget
        clearTimeout(this._timeout); 
     },
     componentWillUnmount: function(){
        // Clear the timeout when the component unmounts
        clearTimeout(this._timeout); 
     },
    ...
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.