Javascript 反应警告,在ComponentDidMount中设置状态(…)

Javascript 反应警告,在ComponentDidMount中设置状态(…),javascript,reactjs,Javascript,Reactjs,我在下面的函数中用setState得到了这个警告,有人能告诉我需要如何构造代码来消除它吗 warning.js:46警告:设置状态(…):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是禁止操作。请检查FileInput组件的代码。 componentDidMount: function () { var self = this; this.initUploader(); this.uploader.init();

我在下面的函数中用setState得到了这个警告,有人能告诉我需要如何构造代码来消除它吗

warning.js:46警告:设置状态(…):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是禁止操作。请检查FileInput组件的代码。

    componentDidMount: function () {
    var self = this;
    this.initUploader();

    this.uploader.init();

    EVENTS.forEach(function (event) {
        var handler = self.props['on' + event];
        if (typeof handler === 'function') {
            self.uploader.bind(event, handler);
        }
    });


   this.uploader.bind('FileUploaded', function (up, file, res) {
        var objResponse = JSON.parse(res.response);
        console.log(objResponse.reference);
        self.props.getFileRef(objResponse.reference);


        var stateFiles = self.state.files;
        _.map(stateFiles, function (val, key) {
            if (val.id === file.id) {
                val.uploaded = true;
                stateFiles[key] = val;
            }
        });
        // setState causing warning
        self.setState({ files: stateFiles }, function () {
            self.removeFile(file.id);
        });
    });

FileUploaded
事件处理程序正在使用闭包
self
引用调用
setState
。这会导致组件卸载时发生泄漏,然后会触发
fileupload
事件,并在卸载的组件上调用setState。你可以在这篇文章中阅读更多关于这方面的内容,这篇文章有点相关-

现在,如何解决这一问题取决于
上传程序
对象是否允许解除绑定事件处理程序。如果允许的话,你可以这样做-

  • FileUploaded
    处理程序代码定义为命名函数(而不是匿名函数)。您需要执行此操作,以便以后能够解除绑定
  • 更改
    componentDidMount
    中的代码,将命名函数绑定为
    FileUploaded
    事件处理程序
  • 组件willunmount
    事件处理程序添加到组件中,并调用
    上传程序的解除绑定机制,将命名的处理程序引用传递给它
  • 这样,当卸载组件时,相应的处理程序也将被删除,并且不再报告此警告

    PS:您应该删除(解除绑定)上面代码中注册的所有处理程序,否则您将到处泄漏引用,更重要的是,将留下大量孤立事件处理程序

    ==更新==

    按你的意思,你可以-

  • 在组件中声明这些新方法-

    registerHandler: function(uploader, event, handler){
        this.handlers = this.handlers || [];
      this.handlers.push({e: event, h: handler});
      uploader.bind(event, handler);
    },
    
    unregisterAllHandlers : function(uploader){
        for (var i = 0; i < this.handlers.length; i++){
            var handler = this.handlers[i],
            e = handler.e,
            h = handler.h;
            // REPLACE with the actual event unbinding method
            // of uploader.
            uploader.unbind(e, h);
            delete this.handlers[i];
        }
    },
    
    componentWillUnmount: function(){
        this.unregisterAllHandlers(this.uploader);
    }
    
    registerHandler:函数(上传程序、事件、处理程序){
    this.handlers=this.handlers | |[];
    push({e:event,h:handler});
    bind(事件、处理程序);
    },
    unregisterAllHandlers:函数(上载程序){
    for(var i=0;i
  • 在调用上载程序的所有位置使用
    registerHandler
    。bind
    -

    self.registerHandler(self.uploader、事件、处理程序)

    this.registerHandler(this.uploader,'FilesAdded',函数(up,files){
    if(u.get(self.props,'multi_selection')==false){…};


  • 这是一个非常粗糙的实现,基本上我们将所有事件处理程序引用存储在一个数组中,然后在卸载过程中删除它们。

    定义了
    self
    的地方?谢谢回复,更新了帖子谢谢回复,你有关于我如何做的代码示例吗?链接文章有很好的代码示例。如果你能吃了一个JSFIDLE,我可以用建议的方法修改它。我这里有一个FIDLE,我已经在componentDidMount中绑定了,