34

Current component has state.breaker value of false. When the scroll event is captured it looks at the state and if its false it does some stuff.

I would like to have some kind of static delay before the action will recur and that's why inside goTo function the state.breaker is set to true and will block the the further logic of current method for next 2s until setTimeout will return back to false.

But at the current moment the following error occurs Uncaught TypeError: this.setState is not a function when setState is called inside setTimeout.

class Slide extends Component {
  constructor(props) {
    super(props)

    this.state = {
      breaker: false
    }

    this.scrollRedirect = this.scrollRedirect.bind(this);
  }

  componentDidMount() {
    this.refs.holder.addEventListener('mousewheel', this.scrollRedirect);
  }


  scrollRedirect(e) {

    const path = this.props.location.pathname,
    goTo = (route) => {
      this.setState({breaker: true});
      hashHistory.push(route);

      setTimeout(function () {
        this.setState({breaker: false});
      }, 2000)
    };

    if (!this.state.breaker) {
       ... code that executes goTo on condition
    }
  }

  ... render code

}
0

1 Answer 1

119

You are loosing context. Use arrow function as simple way to preserve proper execution context:

setTimeout(() => {
  this.setState({breaker: false});
}, 2000)

Remember that anonymous function will have context window inside, unless you explicitly bind it with Function.prototype.bind. So here is another way to solve this problem:

setTimeout(function () {
  this.setState({breaker: false});
}.bind(this), 2000)
2
  • 1
    true, thank you! :)
    – volna
    Commented Mar 7, 2017 at 13:56
  • 6
    Blessed Arrow Functions :) Commented Sep 21, 2018 at 18:13

Not the answer you're looking for? Browse other questions tagged or ask your own question.