Javascript 反应 this.setState 不是一个函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31045716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React this.setState is not a function
提问by Ivan
I'm new in React and I'm trying to write an app working with an API. I keep getting this error:
我是 React 的新手,我正在尝试编写一个使用 API 的应用程序。我不断收到此错误:
TypeError: this.setState is not a function
类型错误:this.setState 不是函数
when I try to handle the API response. I suspect it's something wrong with this binding but I can't figure out how to fix it. Here's the code of my component:
当我尝试处理 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>
);
}
});
回答by Davin Tryon
The callback is made in a different context. You need to bind
to this
in order to have access inside the callback:
回调是在不同的上下文中进行的。您需要这样做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:
Looks like you have to bind both the init
and api
calls:
编辑:看起来你必须同时绑定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');
回答by goodhyun
You can avoid the need for .bind(this) with an ES6 arrow function.
您可以使用 ES6 箭头函数避免对 .bind(this) 的需要。
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);
}
});
回答by user2954463
you could also save a reference to this
before you invoke the api
method:
您还可以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');
},
回答by uruapanmexicansong
React recommends bind this in all methods that needs to use this of class
instead this of self function
.
React 建议在所有需要使用 thisclass
代替 self 的方法中绑定 this function
。
constructor(props) {
super(props)
this.onClick = this.onClick.bind(this)
}
onClick () {
this.setState({...})
}
Or you may to use arrow function
instead.
或者你可以arrow function
改用。
回答by g8bhawani
You just need to bind your event
你只需要绑定你的事件
for ex-
对于前-
// place this code to your constructor
this._handleDelete = this._handleDelete.bind(this);
// and your setState function will work perfectly
_handleDelete(id){
this.state.list.splice(id, 1);
this.setState({ list: this.state.list });
// this.setState({list: list});
}
回答by Sameel
Now ES6 have arrow function it really helpful if you really confuse with bind(this) expression you can try arrow function
现在 ES6 有了箭头函数,如果你真的对 bind(this) 表达式感到困惑,你可以试试箭头函数,这真的很有帮助
This is how I do.
这就是我的做法。
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));
}
回答by Hemadri Dasari
You no need to assign this to a local variable if you use arrow function. Arrow functions takes binding automatically and you can stay away with scope related issues.
如果使用箭头函数,则无需将其分配给局部变量。箭头函数自动进行绑定,您可以远离与作用域相关的问题。
Below code explains how to use arrow function in different scenarios
下面的代码解释了如何在不同场景下使用箭头函数
componentDidMount = () => {
VK.init(() => {
console.info("API initialisation successful");
VK.api('users.get',{fields: 'photo_50'},(data) => {
if(data.response){
that.setState({ //this available here and you can do setState
FirstName: data.response[0].first_name
});
console.info(that.state.FirstName);
}
});
}, () => {
console.info("API initialisation failed");
}, '5.34');
},
回答by Quentin Malguy
Now in react with es6/7 you can bind function to current context with arrow function like this, make request and resolve promises like this :
现在在与 es6/7 反应中,您可以使用这样的箭头函数将函数绑定到当前上下文,发出请求并解决如下承诺:
listMovies = async () => {
const request = await VK.api('users.get',{fields: 'photo_50'});
const data = await request.json()
if (data) {
this.setState({movies: data})
}
}
With this method you can easily call this function in the componentDidMount and wait the data before render your html in your render function.
使用此方法,您可以轻松地在 componentDidMount 中调用此函数并在渲染函数中渲染 html 之前等待数据。
I don't know the size of your project but I personally advise against using the current state of the component to manipulate datas. You should use external state like Redux or Flux or something else for that.
我不知道您的项目的大小,但我个人建议不要使用组件的当前状态来操作数据。您应该为此使用外部状态,例如 Redux 或 Flux 或其他东西。
回答by Pranav Kapoor
use arrow functions, as arrow functions point to parent scope and this will be available. (substitute of bind technique)
使用箭头函数,因为箭头函数指向父作用域,这将可用。(替代绑定技术)
回答by Shubham Gupta
Here THIS context is getting changed. Use arrow function to keep context of React class.
这里这个上下文正在发生变化。使用箭头函数来保持 React 类的上下文。
VK.init(() => {
console.info("API initialisation successful");
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);
}
});
}, function(){
console.info("API initialisation failed");
}, '5.34');