react this.setState 不是一个函数

IT技术 javascript reactjs
2021-02-09 22:16:34

我是 React 的新手,我正在尝试编写一个使用 API 的应用程序。我不断收到此错误:

类型错误: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>
        );
    }
});
6个回答

回调是在不同的上下文中进行的。您需要这样做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));

编辑:看起来你必须同时绑定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');
圣。我花了几个小时,我可以做一个绑定?....至少它现在工作
2021-03-17 22:16:34
有人可以进一步详细说明“在不同的上下文中进行回调”是什么意思?
2021-03-23 22:16:34
大概是 2.5 年前。😁
2021-03-26 22:16:34
@TravisReeder,不。教程中没有提到绑定。
2021-04-02 22:16:34
我用箭头函数来解决这个问题。谢谢您的帮助
2021-04-03 22:16: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);
        }

    });
只要您不需要支持旧浏览器,这很好。
2021-03-21 22:16:34
完美解决方案
2021-04-01 22:16:34
您的回答对我有所帮助:-) 使用 ES6 类和 RN 0.34,我找到了两种将“this”绑定到回调函数的方法。1) onChange={(checked) => this.toggleCheckbox()}, 2) onChange={this.toggleCheckbox.bind(this)}
2021-04-04 22:16:34
GMsoF,这两个解决方案之所以有效,是因为 a) 当你这样做时.bind(this),它会将 的值设置为被调用this的父上下文this.toggleCheckbox(),否则this将引用它实际执行的位置。b) 粗箭头解决方案之所以有效,是因为它保留了 的值this,因此它通过不剧烈改变 的值来帮助您this在 JavaScript 中,this简单地指代当前作用域,所以如果你写一个函数,this就是那个函数。如果你把一个函数放在里面,它就this在那个子函数里面。粗箭头保持从哪里调用的上下文
2021-04-07 22:16:34
这很好用。实际上,函数的关键字不应该出现在es6的文件中。
2021-04-10 22:16:34

React 建议在所有需要使用 thisclass代替 self 的方法中绑定 this function

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

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

或者你可以arrow function改用。

您还可以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');
},

你只需要绑定你的事件

对于前-

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

}