Getting error as "Unhandled Rejection (TypeError): that.setState is not a function" in ReactJS

990 Views Asked by At

I am currently working on a dynamic chart which change based on Slider value. I searched for a solution, and everyone says I need to bind it to get this error go away. However I have tried to bind the function in all possible ways still I get this error:

Unhandled Rejection (TypeError): that.setState is not a function.

Relevant code:

class Home extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0,
      slideValue: 200,
      slidebgColor: "47CF8E",
      type: 'bar',
      data: {
        labels: [0],
        datasets: [{
          label: '',
          data: [0, 1],
          backgroundColor: [
            'rgba(255, 99, 132, 0.2)'
          ]
        }]
      },
      options: {
        legend: {
          display: false
        },
        scales: {
          yAxes: [{
            display: false,
            ticks: {
              beginAtZero: true,
              autoskip: true
            }
          }],
          xAxes: [{
            display: false
          }]
        }
      }
    }
    this.handleSliderEvent = this.handleSliderEvent.bind(this);
  }

  componentDidMount() {
    console.log("inside componentDidMount");
  }

  getChartData = e => {
    const data1 = this.state.data;
    const slideValue = this.state.slideValue;
    const backColor = ["pink", "purple", "blue", "green", "lightblue", "neon", "red", "lightgreen", "yellow", "grey", "lightgrey", "orange"]

    for (let i = 0; i < slideValue; i++) {
      const randomNumber = Math.ceil(Math.random() * slideValue);

      data1.labels[i] = randomNumber;
      data1.datasets[0].data[i] = randomNumber;
      data1.datasets[0].backgroundColor[i] = "purple";
    }

    this.setState = {
      data: data1
    }

    return data1;
  }

  handleSliderEvent = async (event) => {
    let slideValue1 = event;
    let that = this;

    that.setState({
      slideValue: slideValue1
    })
  };

  render() {
    const type = this.state.type;
    const options = this.state.options;
    const data = this.state.data;
    const slideValue = this.state.slideValue;
    const value = this.state.value;

    return (
      <div style={{ display: "inline-flex" }}>
        <div style={{ height: 400, display: "inline-flex", paddingLeft: "20px" }}>
          <Slider
            defaultValue={200}
            vertical
            progress
            min={0}
            max={this.state.slideValue}
            onChange={this.handleSliderEvent}
          />
        </div>
        <div style={{ display: "inline-flex", position: "relative", width: 600, height: 550, paddingLeft: "10%" }}>
          <Bar
            type={type}
            options={options}
            data={this.getChartData}
          />
        </div>
      </div>
    );
  }
}

export default Home;

Can anyone please suggests what went wrong?

3

There are 3 best solutions below

8
On

You're calling:

that.setState(...);

Rather than:

this.setState(...);

Your code should look like this:

handleSliderEvent = async (event) => {
    let slideValue1 = event;
    // let that=this;

    console.log("slideValue :", slideValue1)

    //that.setState ({
    this.setState({
        slideValue: slideValue1
    });

    console.log(this.state.slideValue);
};
6
On

Is there a reason to use let that = this?

Isn't it better to do something like:

 handleSliderEvent = async (event) => {
    
        this.setState({
            slideValue: event
        })
      };

Besides that I believe your TypeError come from other place:

getChartData=e=>{
...

this.setState = { data: data1 }

Instead of using:

 this.setState({ data: data1 })
4
On

The problem is with this bit of code inside getChartData:

this.setState = {
  data: data1
}

You're reassigning the setState function instead of calling it with updated data. This means the next time you attempt to call this.setState it will break, because now it is an object instead of a function. Simply change it to this:

this.setState({
  data: data1
})

Also, as stated in the comments: let that = this is useless as well as the binding in the contructor. An arrow function does not need that workaround.