这个反应。setState不是一个函数

我是React的新手,我正在尝试编写一个使用API的应用程序。我一直得到这个错误:

TypeError:这个。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>
);
}
});
466118 次浏览

回调是在不同的上下文中进行的。你需要bindthis来访问回调函数:

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));
< p >编辑: 看起来你必须同时绑定initapi调用:

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

你也可以在调用api方法之前保存对this的引用:

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)。

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


});

现在ES6有箭头函数,它真的很有用,如果你真的混淆了bind(这个)表达式,你可以试试箭头函数

我就是这么做的。

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

现在在react with 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})
}
}

使用这个方法,你可以很容易地在componentDidMount中调用这个函数,并在渲染函数中渲染html之前等待数据。

我不知道你项目的大小,但我个人建议不要使用组件的当前状态来操作数据。 你应该使用外部状态比如Redux或者Flux或者其他的。< / p >

您只需要绑定您的事件

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


}

如果您使用箭头函数,则不需要将此分配给局部变量。箭头函数自动接受绑定,您可以避开范围相关的问题。

下面的代码解释了如何在不同的场景中使用箭头函数

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

React建议在所有需要使用class的this而不是self function的this的方法中绑定this。

constructor(props) {
super(props)
this.onClick = this.onClick.bind(this)
}


onClick () {
this.setState({...})
}

或者你可以使用arrow function代替。

在这里,这个上下文正在发生变化。使用箭头函数保持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');

如果你这样做仍然有问题,我的问题是我调用了两个相同的变量名。

我有companies作为一个从Firebase引入的对象,然后试图调用this.setState({companies: companies}) -由于明显的原因它不起作用。

使用箭头函数,因为箭头函数指向父范围,这将是可用的。 (代替绑定技术)

使用from 箭头功能来处理动作。

这主要是反应体、反应体和酶之间的不相容问题。

尝试像我那样安装以下程序来解决问题:

[...]
"react": "^18.0.0-beta-f320ef88f-20211116",
"react-dom": "16.14.0",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.6"
[...]

我有同样的误差

TypeError: setState is not a function

但是这个理由是愚蠢的。把它作为回应发布在这里,希望能拯救那些可能犯同样错误的人。

而不是

  const { state, setState } = React.useState(false);

使用

  const [ state, setState ] = React.useState(false);

广场括号而不是大括号!

在我的情况下,问题是我发送的状态和setstate作为道具的子组件,但在setstate有一个打字错误