Tom
Tom

Reputation: 8180

react: "Can only update a mounted or mounting component."

The setState call in question is working despite the warning. The warning only occurs after the component on which I am calling setState has been removed, and then rerendered. Why am I getting this warning when the component is already mounted?

<div id="contentArea">

     {this.state.activePlugin?this.state.activePlugin.render():null}

</div>

the render method returns a react element:

render(){ 

    return <DatasetsList />;

}

state.activePlugin is set to null and the component containing the jsx code above is rerendered, this is how removing the 'activePlugin' happens. When render is called again and returns the <DatasetsList /> for the second time, subsequent clicks inside the component produce this warning, despite the fact that the setState calls they initiate in fact work as expected.

In other words, the warning appears to be misleading, as the code is working as expected.

 componentDidMount() { 
        this.unsubscribe = this.props.store.listen(s=>{
          this.setState(s);
        });
    }

Upvotes: 1

Views: 941

Answers (2)

Taylor Allred
Taylor Allred

Reputation: 4380

https://jsfiddle.net/taylorallred/69z2wepo/29874/

var Hello = React.createClass({
  getInitialState: function() {
    return {
      activePlugin: Plugin
    }
  },

  togglePlugin: function() {
    this.setState({
      activePlugin: this.state.activePlugin ? null : Plugin
    })
  },

  render: function() {
    return <div >
      < div onClick = {
        this.togglePlugin
      } > Hello {
        this.props.name
      } < /div> < div > {
        this.state.activePlugin ? < Plugin / > : null
      } < /div> < /div>;
  }
});

var Plugin = React.createClass({
  render: function() {
    return ( < MyComponent / > );
  }
});

var MyComponent = React.createClass({
  getInitialState:function(){
    return {a: 1};
  },
    componentDidMount:function(){
     window.setInterval(function(that){that.setState({a: that.state.a++})}, 2000, this);
  },

    render: function() {
        var a = this.state.a;
    return <div > MyComponent { a }< /div>;
  }
});

ReactDOM.render( < Hello name = "World" / > ,
  document.getElementById('container')
);

It's probably because your component is receiving updates when it's not rendered and that component is trying to render because it's state changed. See the fiddle. Click to remove the component and you'll get that error in the console.

Upvotes: 3

Tom
Tom

Reputation: 8180

The warning was referring to the old unmounted instance of my component which was still listening to the store, as shown in the question. Simply unsubscribing from the store inside componentWillUnmount solved the issue.

  componentWillUnmount() {
        this.unsubscribe();
    }

Upvotes: 0

Related Questions