Oscar
Oscar

Reputation: 855

Warning: Cannot update during an existing state transition

I have a complex app and it gives me the following warning:

Warning: setState(...): Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount.

In two words this warning occurs when I press an 'add' button, that should add another component to my app. Here is a corresponding piece of code:

<Button onClick={addChartHandler.bind(this)}><Glyphicon glyph="plus" /></Button>

addChartHandler comes from it's container component:

addChartHandler() {
    store.dispatch(addChart());
}

addChart simply increases the components counter. And the app container subscribes to these changes:

const mapStateToProps = (store) => {
    return {
        count: store.app.chartsCount
    };
}

It's hard for me to trace the warning, but I called console.log each time every component renders. It appears that this warning pops out after rendering this component (which is dumb component for my App):

render() {
    let charts = [];

    for (let i = 0; i < this.props.count; i++) {
        charts.push(<ChartContainer id={i} key={i} size={this.props.size} />);
    }
    console.log('APP RENDER');
    console.log(charts);
    return (
        <div className="container-padding">
            <NavContainer />
            {charts}
        </div>
    );
}

Any suggestions are welcome. Been working on that for at least three hours, ran out of ideas.

Upvotes: 0

Views: 3844

Answers (3)

Oscar
Oscar

Reputation: 855

Thanks for all the answers, I solved the issue: I was invoking setState in some other component's constructor(). For those either looking: double-check all of your other components, and their render() and constructor() methods.

Upvotes: 0

Tejashree
Tejashree

Reputation: 820

This solution helps me to clear my thoughts.

I was facing that error because I added this.setState({}); in constructor it self.

So I moved it to componentWillReceiveProps and It worked!

Thank you @Harkirat Saluja

Upvotes: 0

Harkirat Saluja
Harkirat Saluja

Reputation: 8114

This is the line of code because of code which causes the issue I feel:-

  for (let i = 0; i < this.props.count; i++) {
        charts.push(<ChartContainer id={i} key={i} size={this.props.size} />);
    }

I think you are doing setState somewhere in render or your state is updating where it should not do. Can you share you ChartContainer component once?

Can you try this out?

constructor(){
   state : {
     charts : []
  } 
}

componentWillReceiveProps(nextProps){
  if(nextProps.count != this.props.count){
     let charts = []
     for (let i = 0; i < this.props.count; i++) {
        charts.push(<ChartContainer id={i} key={i} size={this.props.size}      />);
    }
   this.setState({charts:charts})
  }
}

render() {
    return (
        <div className="container-padding">
            <NavContainer />
            {this.state.charts}
        </div>
    );
}

Upvotes: 2

Related Questions