0
votes

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+?

1
Possible duplicate of How does the "this" keyword work?trincot
Define const colors = ['green', 'red', 'blue', 'yellow']; and just call this.setState({color: colors[compArr[i] - 1]}). No wrapping functions needed.Sulthan
ES7 was released last year. You are talking about an experimental feature.Felix Kling

1 Answers

0
votes

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))
}
};