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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:06:52  来源:igfitidea点击:

React this.setState is not a function

javascriptreactjs

提问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 bindto thisin 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 initand apicalls:

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

回答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 thisbefore you invoke the apimethod:

您还可以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 classinstead 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 functioninstead.

或者你可以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');