0

I'm using property initializers. This is my state.

 state = {
 status: 'Simon Says!',
 compArr: [],
 color: 'red',
 userArr: []
};

This is my pen.

I call the state here

game = (event) => {
 let compArr = this.state.compArr;
 for (let i = 0; i < compArr.length; i++) {
  (function(i) {
    setTimeout(function() {
      switch (compArr[i]) {
        case 1:
          this.setState({
            color: 'green'
          });
          break;
        case 2:
          this.setState({
            color: 'red'
          });
          break;
        case 3:
          this.setState({
            color: 'yellow'
          });
          break;
        case 4:
          this.setState({
            color: 'blue'
          });
          break;
      }
    }, 1000 * i);
  }(i))
}
};

I get the following error

Uncaught TypeError: this.setState is not a function

How do I fix this in ES2015+?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
furball514
  • 273
  • 2
  • 4
  • 15
  • 4
    Possible duplicate of [How does the "this" keyword work?](http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – trincot Apr 15 '17 at 11:35
  • Define `const colors = ['green', 'red', 'blue', 'yellow'];` and just call `this.setState({color: colors[compArr[i] - 1]})`. No wrapping functions needed. – Sulthan Apr 15 '17 at 11:50
  • ES7 was released *last year*. You are talking about an *experimental feature*. – Felix Kling Apr 15 '17 at 21:30
  • Possible duplicate of [How to access the correct \`this\` inside a callback?](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Felix Kling Apr 15 '17 at 21:32

1 Answers1

0

The problem is that this doesn't refer to the correct context inside the setTimeout function ,you can do it the follwoing way

game = (event) => {
 var self = this;
 let compArr = this.state.compArr;
 for (let i = 0; i < compArr.length; i++) {
  (function(i) {
    setTimeout(function() {
      switch (compArr[i]) {
        case 1:
          self.setState({
            color: 'green'
          });
          break;
        case 2:
          self.setState({
            color: 'red'
          });
          break;
        case 3:
          self.setState({
            color: 'yellow'
          });
          break;
        case 4:
          self.setState({
            color: 'blue'
          });
          break;
      }
    }, 1000 * i);
  }(i))
}
};

CODEPEN

You can simplyfy your logic by using an array

game = (event) => {
 var self = this;
 let compArr = this.state.compArr;
 var color = ["green", "red", "yellow", "blue"];
 for (let i = 0; i < compArr.length; i++) {
  (function(i) {
    setTimeout(function() {
      self.setState({color: color[compArr[i] - 1]});
    }, 1000 * i);
  }(i))
}
};
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400