1

I want to make a DynamicBarChart, but I am unable to update the state. Could you figure out why?

import React, { Component } from 'react';
import { DynamicBarChart } from 'react-dynamic-charts';
import 'react-dynamic-charts/dist/index.css';

class Dynamicchart extends Component {
  constructor(props) {
    super(props)

    this.state = {
      data: [{ "name": "Call", "values": [] }]
    }
  }

  componentDidMount = async () => {
    const mockData = [
      {
        id: 1,
        value: 10,
        label: "hey",
        color: "red"
      }
    ]
    const newwData = [{
      "name": "Call1",
      "values": mockData // Here i changed the values of the data
    }]

    this.setState({
      data: newwData // This method is unable to change the state.data component
    });

    // This still gives the value of data which is given in constructor 
    // Why has the value not changed?
    console.log(this.state.data) 
  }

  render() {
    return (
      <DynamicBarChart
        data={this.state.data}
      />
    );
  }
}

export default Dynamicchart

This code is showing "Call" in front-end, I want the value of "Call1". This means that the state did not change. Can you explain why this is happening?

Kate Orlova
  • 3,225
  • 5
  • 11
  • 35
  • 1
    `setState` is async, it will not be updated immediately after calling the updater. Log inside of the `render` instead and you will see the updated values. – Brian Thompson May 13 '20 at 15:51
  • Also, attempting to change the state of an object in `componentDidMount` from what was set in the `constructor` could be contributing to the problem. Why set it in both places? – markp May 13 '20 at 15:54
  • [Docs on `setState`](https://reactjs.org/docs/react-component.html#setstate) that explains the behavior of `setState`. [In depth answer](https://github.com/facebook/react/issues/11527#issuecomment-360199710). – Brian Thompson May 13 '20 at 15:58
  • 1
    Does this answer your question? [Why calling react setState method doesn't mutate the state immediately?](https://stackoverflow.com/questions/30782948/why-calling-react-setstate-method-doesnt-mutate-the-state-immediately) – Brian Thompson May 13 '20 at 16:02
  • render() { console.log(this.state.data) return ( ); } } //yes i did this but still the value showing in front end is call instead of call1 – komal rawat May 13 '20 at 17:27

2 Answers2

0

setState is an Async operation so you have to use callback for doing anything after setState, use console.log() in this way in the callback or put console.log in the render function.

    const newwData = [{
      "name": "Call1",
      "values": mockData
    }]

    this.setState({
      data: newwData
    }, () => console.log(this.state.data));
Bassem
  • 3,582
  • 2
  • 24
  • 47
Waheed Akhtar
  • 3,110
  • 1
  • 16
  • 30
0

Adding a random key to the DynamicBarChart component will solve the issue:

    return <DynamicBarChart key={Math.random()} data={this.state.data} />;

I created a sandbox to demonstrate this with a fake delay in this Example with Simulated API Request.


That being said, the comment of @Waheed is valid, regarding accessing this.state.data right after calling this.setState({...}) as the latter is async. If you want to see the data update, use the console.log in the render() block or as a callback of the setState like @Waheed mentioned in his reply.

The reason why the component is not re-rendering is because you're mutating the state with new data. By setting a random key you're forcing the DynamicBarChart component re-rendering.

Bassem
  • 3,582
  • 2
  • 24
  • 47