2015-06-25 3 views
109

Я новичок в React, и я пытаюсь написать приложение, работающее с API. Я продолжаю получать эту ошибку: TypeError: this.setState не является функцией, когда я пытаюсь обработать ответ API. Я подозреваю, что это неправильно, но я не могу понять, как это исправить. Вот код моего компонента:React this.setState не является функцией

var AppMain = React.createClass({ 
    getInitialState: function() { 
     return{ 
      FirstName: " " 
     }; 
    }, 
    componentDidMount:function(){ 
     VK.init(function(){ 
      console.info("API initialisation successful"); 
      VK.api('users.get',{fields: 'photo_50'},function(data){ 
       if(data.response){ 
        this.setState({ //the error happens here 
         FirstName: data.response[0].first_name 
        }); 
        console.info(this.state.FirstName); 
       } 

      }); 
     }, function(){ 
     console.info("API initialisation failed"); 

     }, '5.34'); 
    }, 
    render:function(){ 
     return (
      <div className="appMain"> 
      <Header /> 
      </div> 
     ); 
    } 
}); 

ответ

158

Обратный вызов осуществляется в другом контексте. Вы должны bind к this для того, чтобы иметь доступ внутри обратного вызова:

VK.api('users.get',{fields: 'photo_50'},function(data){ 
    if(data.response){ 
     this.setState({ //the error happens here 
      FirstName: data.response[0].first_name 
     }); 
     console.info(this.state.FirstName); 
    } 

}.bind(this)); 

EDIT: Похоже, вы должны связать оба init и api вызовы:

VK.init(function(){ 
     console.info("API initialisation successful"); 
     VK.api('users.get',{fields: 'photo_50'},function(data){ 
      if(data.response){ 
       this.setState({ //the error happens here 
        FirstName: data.response[0].first_name 
       }); 
       console.info(this.state.FirstName); 
      } 

     }.bind(this)); 
    }.bind(this), function(){ 
    console.info("API initialisation failed"); 

    }, '5.34'); 
+0

шоу это в учебнике: http://facebook.github.io/react/docs/tutorial.html –

29

можно также сохранить ссылка на this, прежде чем вы обратитесь к методу api:

componentDidMount:function(){ 

    var that = this; 

    VK.init(function(){ 
     console.info("API initialisation successful"); 
     VK.api('users.get',{fields: 'photo_50'},function(data){ 
      if(data.response){ 
       that.setState({ //the error happens here 
        FirstName: data.response[0].first_name 
       }); 
       console.info(that.state.FirstName); 
      } 
     }); 
    }, function(){ 
     console.info("API initialisation failed"); 

    }, '5.34'); 
}, 
61

Вы можете избежать необходимости .bind (this) с помощью функции стрелки ES6.

VK.api('users.get',{fields: 'photo_50'},(data) => { 
     if(data.response){ 
      this.setState({ //the error happens here 
       FirstName: data.response[0].first_name 
      }); 
      console.info(this.state.FirstName); 
     } 

    }); 
+0

Это хорошо работает. На самом деле ключевое слово функции не должно отображаться в файле es6. –

+4

Ваш ответ помог мне :-) Используя класс ES6 и RN 0.34, я нашел два способа привязать «это» к функции обратного вызова. 1) 'onChange = {(checked) => this.toggleCheckbox()}', 2) 'onChange = {this.toggleCheckbox.bind (this)}'. – devdanke

+0

может помочь объяснить, как эта работа? – GMsoF

2

Теперь ES6 есть стрелка функция это действительно полезно, если вы действительно перепутать с безвыходном (это) выражение, которое вы можете попробовать функцию стрелки

Это, как я.

componentWillMount() { 
     ListApi.getList() 
      .then(JsonList => this.setState({ List: JsonList })); 
    } 

//Above method equalent to this... 
    componentWillMount() { 
     ListApi.getList() 
      .then(function (JsonList) { 
       this.setState({ List: JsonList }); 
      }.bind(this)); 
} 
Смежные вопросы