Ashok
Ashok

Reputation: 311

How to update child component If parent state value change

I have a dashboard in which I am filtering data with search fields. On change of data of state, I want to reload graph component where I have passed state property as data value.

const intialState = {
    graphData:  null,
    costCenterList: [],
    costCenterValue: []
};
class Dashboard extends Component {
  constructor(props){
    super(props);
    this.state = intialState;
    this.handleCostCenterChange = this.handleCostCenterChange.bind(this);
  }
  handleCostCenterChange(event, values){     
    var filtered = this.state.graphData.filter(el => values.includes(el.costCode));
    this.setState({graphData: filtered});
  }

  render() { 
    <Grid item md={2}>
        <div>
          <InputLabel id="costCenterLabel" style= {{textAlign:'left', fontWeight:'bold'}}>Cost Center</InputLabel>
           <FormControl style={{minWidth:'200px', width:'100%'}} variant="outlined" >
              <Autocomplete
                  multiple
                  options={this.state.costCenterList.map((p) => p)}
                  renderInput={params => (
                    <TextField {...params} margin="normal" variant="outlined" fullWidth autoComplete="off" />
                  )}
                  onChange={this.handleCostCenterChange}
              />
           </FormControl>
        </div>
      </Grid>

      <Grid item md={12}>
        <BarGraph graphData={this.state.graphData}/>
      </Grid>
  }

 }

Code of BarGraph is as follows:

export default class BarGraph extends Component {
  state = {
    dataForChart: {
      datasets: [
      ]
    }
  }

  render() {
    return (
      <div>
        <h3>Hours Per Cost Center</h3>
        <Bar ref="chart" data={this.state.dataForChart} options = {this.state.barChartOptions} height={242} width={486}/>
      </div>
    );
  }


  componentDidMount() {
    try {

      let graphData = this.props.graphData;
      let newState = Object.assign({}, this.state);

      newState.dataForChart.datasets =[{barPercentage: 1, label:'Hours Per Cost Center ', data : graphData, backgroundColor : oBarColours, borderWidth:2, borderColor:oBarColours}];
      newState.dataForChart.labels = oCostCenterDistinct;

      this.setState(newState);
      } catch (error) {
      console.log("Network error: " + error);
    }
  }

}

I want to update component on change of graphData of state. On change with this.setState its updating value of state but not component with new data.

Can any one please help what I am missing here?

Upvotes: 2

Views: 218

Answers (1)

Drew Reese
Drew Reese

Reputation: 202605

Need to respond to prop updates. Factor out your data processing into a utility function that is called when the component mounts, and again on updated to props.

export default class BarGraph extends Component {
  state = {
    dataForChart: {
      datasets: []
    }
  };

  setData() {
    try {
      const { graphData } = this.props;
      const newState = { ...this.state };

      newState.dataForChart.datasets = [
        {
          barPercentage: 1,
          label: "Hours Per Cost Center ",
          data: graphData,
          backgroundColor: oBarColours,
          borderWidth: 2,
          borderColor: oBarColours
        }
      ];
      newState.dataForChart.labels = oCostCenterDistinct;

      this.setState(newState);
    } catch (error) {
      console.log("Network error: " + error);
    }
  }

  componentDidMount() {
    this.setData();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.graphData !== this.props.graphData) {
      this.setData();
    }
  }

  render() {
    return (
      <div>
        <h3>Hours Per Cost Center</h3>
        <Bar
          ref="chart"
          data={this.state.dataForChart}
          options={this.state.barChartOptions}
          height={242}
          width={486}
        />
      </div>
    );
  }
}

Upvotes: 4

Related Questions