[Chartjs]-Why is the child component updating but not re-render Reactjs

6👍

I see one problem and that is you are not changing object references in this.state.errorChart upon errorChart update before you call setState. Even though you push to its properties new items, the object and even the inner array references do not change, and if the Line component does some props checking on whether it should rerender itself or not, it figures by receiving still the same references that nothing has changed and there is no need to rerender.

Now this was just my assumption, but either way it is a good practice to always create new objects while creating new state once those objects are about to be modified. This allows for fast object (state) references comparisons in shouldComponentUpdate methods or while using PureComponentwhich in turn makes it easier and more performant to determine whether to rerender the component or not. On the other hand, if you would use the same references still, you would have to implement deep comparison of the old and the new state, which is definitely more expensive and very fragile in the long run.

Example on how to correctly update the state follows:

createInitialChart(data) {
  const errorChart = this.state.errorChart

  const newErrorChart = {
    ...errorChart
  }

  newErrorChart.labels = [...errorChart.labels, data.map(row => row.time_stamp)]
  newErrorChart.datasets[0].data = [
    ...errorChart.datasets[0].data,
    data.map(row => row.error)
  ]

  this.setState({ errorChart: newErrorChart })
}

Edit:
By looking at the component’s shouldComponentUpdate implementation – ChartComponent, It can be clearly seen, that there are multiple options on how to make the Line rerender, eg. by giving redraw={true} prop to the Line component. The procedure above is generally still the safest way to ensure rerender though.

0👍

You might need componentWillReceiveProps(nextProps, nextState).
You can compare the old state here with the new state and update the state accordingly.

Please set the initialState like so:

constructor(props){
 super(props);
 this.state = {errorChart: {...}}; //your initial values here.
}

then,

componentWillReceiveProps(nextProps, nextState){
 if(this.state.errorChart !== nextState.errorChart){
   let tempErrorChart = {...this.state.errorChart};
    for (let row of data){
        tempErrorChart.labels.push(row.time_stamp);
        tempErrorChart.datasets[0].data.push(row.error);
    }
    this.setState({errorChart: tempErrorChart});
 }
}

Leave a comment