Я новичок в React, и я пытаюсь написать приложение, работающее с API. Я продолжаю получать эту ошибку: TypeError: this.setState не является функцией, когда я пытаюсь обработать ответ API. Я подозреваю, что это неправильно, но я не могу понять, как это исправить. Здесь код моего компонента:
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>
);
}
});
Обратный вызов выполняется в другом контексте. Для доступа к обратному вызову необходимо 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');
Вы можете избежать необходимости .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);
}
});
onChange={(checked) => this.toggleCheckbox()}
, 2) onChange={this.toggleCheckbox.bind(this)}
.
вы также можете сохранить ссылку на 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');
},
Теперь ES6 имеет функцию стрелки, это действительно полезно, если вы действительно путаете с выражением bind (this), вы можете попробовать функцию стрелки
Вот как я это делаю.
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));
}