React Uncaught TypeError: this.setState не является функцией

Я использую инициализаторы свойств. Это мое состояние.

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

Это моя ручка.

Я звоню государству здесь

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

Я получаю следующую ошибку

Uncaught TypeError: this.setState не является функцией

Как исправить это в ES2015+?


person furball514    schedule 15.04.2017    source источник
comment
Возможный дубликат Как работает это ключевое слово?   -  person trincot    schedule 15.04.2017
comment
Определите const colors = ['green', 'red', 'blue', 'yellow']; и просто вызовите this.setState({color: colors[compArr[i] - 1]}). Никаких функций обертывания не требуется.   -  person Sulthan    schedule 15.04.2017
comment
ES7 был выпущен в прошлом году. Вы говорите об экспериментальной функции.   -  person Felix Kling    schedule 16.04.2017
comment
Возможный дубликат Как получить доступ к правильному `this` внутри обратного вызова ?   -  person Felix Kling    schedule 16.04.2017


Ответы (1)


Проблема в том, что это не относится к правильному контексту внутри функции setTimeout, вы можете сделать это следующим образом.

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

Вы можете просто упростить свою логику, используя массив

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))
}
};
person Shubham Khatri    schedule 15.04.2017
comment
вы также можете использовать стрелочные функции для достижения этого без переменной self - person thedude; 15.04.2017
comment
@thedude да, это тоже другой способ. - person Shubham Khatri; 15.04.2017
comment
@Sulthan, может быть, нет, потому что он использует функцию setTimeout внутри forloop , если он удалит эту функцию, он вполне может получить только последнее значение во всех функциях, кстати, его логика определенно может быть упрощена, как вы предлагаете. - person Shubham Khatri; 15.04.2017
comment
@ShubhamKhatri Я имел в виду function(i), я даже не заметил, что внутри есть еще один function() :) Вы правы. - person Sulthan; 15.04.2017
comment
@Султан, без проблем :) - person Shubham Khatri; 15.04.2017