if(this.isMounted())没被调用?

时间:2015-09-09 00:35:19

标签: reactjs

你能告诉我为什么这样做:

 var SomeComponent = React.createClass({

 getData: function(){

 if (this.isMounted()){

  var queryInfo = {
    userId: sessionStorage.getItem("user_id"),
    userRole: sessionStorage.getItem('user_role'),
    aptId : this.props.params
  }

  io = io.connect();
  io.emit('allTasks', queryInfo);
  io.on('allTasksInfo', function(data){
    reqwest({
      url: '/apartment/tasks/address',
      method: 'get',
      xhrFields: {withCredentials: true},
      crossOrigin: true
    }).then(function(data){
       this.setState({
         dataSet: arr
       })
    }.bind(this));
   }.bind(this));
  }
},

componentDidMount: function(){
    this.getData();
},

render: function(){...}

});

执行if中的代码,但是我得到了Uncaught Error:Warning:setState(...):只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState()。这是一个无操作。

但是当我这样做时:

var SomeComponent = React.createClass({

getData: function(){

    var queryInfo = {
     userId: sessionStorage.getItem("user_id"),
     userRole: sessionStorage.getItem('user_role'),
     aptId : location.pathname.split("/")[4]
    }

    reqwest({
        url:'/operation/staff',
        method: 'get',
        xhrFields: {withCredentials: true},
        crossOrigin: true
    }).then(function(data){
        if(this.isMounted()){
            this.setState({
                operationStaff: data
            })
        }
    }.bind(this));
 }

 componentDidMount: function(){
   this.getData();
 },

 render: function(){...}

});

一切都好。安装组件时是否应该首先执行?我缺少什么?

编辑:我正在使用react-router和express服务器与socket.io与服务器呈现(只是组件,而不是数据 - 我将获取客户端)。答案结束后,我可以说:

但是如果我更改了url并返回到此路径(并且这里是,则组件卸载当然), Ajax reqwest 被调用2次 https://drive.google.com/file/d/0B1rbX9C6kejlUjFRYTBtejVLZGs/view?usp=sharing

这与套接字实现有关。

我将关闭此问题,并就此开启另一个问题。谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

  

安装组件时,不应该先执行第一个吗?

是的,它是(是什么让你觉得它不是?)。

但是, Ajax回调本身将在未来的某个时间执行,此时,该组件可能已经卸载。

在第一个示例中,测试没用,因为在调用componentDidMount之后始终会安装组件。在第二个示例中,您正在测试是否在调用setState之前安装了组件,这更有意义。

这是一个简化的例子:

var Hello = React.createClass({
    getInitialState: function() {
        return {name: 'foo'};
    },

    componentDidMount: function() {
        console.log('mounted...');

        setTimeout(function() {
            // this works fine
            console.log('updating state once...');
            this.setState({
                name: 'bar'
             });
        }.bind(this), 1000);

        setTimeout(function() {
            // this will throw
            console.log('updating state twice...');
            this.setState({
                name: 'baz'
             });
        }.bind(this), 3000);
    },

    componentWillUnmount: function() {
        console.log('unmounting...');
    },

    render: function() {
        return <div>Hello {this.state.name}</div>;
    }
});

React.render(
  <Hello />,
  document.getElementById('container')
);

setTimeout(function() {
    React.unmountComponentAtNode(
        document.getElementById('container')
    );
}, 2000);

如果你运行它,你会注意到第二个超时会产生相同的错误,因为它是在卸载组件后调用的:

控制台输出:

mounted...
updating state once...
unmounting...
updating state twice...
 Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op.

DEMO:https://jsfiddle.net/pkzfbcr5/

答案 1 :(得分:0)

我使用react-router和express服务器与socket.io与服务器呈现(只是组件,而不是数据 - 我将获取客户端)。答案结束后,我可以说:

但是如果我更改了url并返回到此路径(并且这里是,则组件卸载当然),Ajax reqwest被调用2次https://drive.google.com/file/d/0B1rbX9C6kejlUjFRYTBtejVLZGs/view?usp=sharing

这与套接字实现有关。

我将关闭此问题,并就此开启另一个问题。谢谢你的帮助。

相关问题