首页 文章

单击按钮时,React setState()不更新状态

提问于
浏览
3

我是React的新手,并尝试使用react-chartjs-2测试一些图表组件 . 我有两个测试数据对象,我希望在按下更新按钮时切换 .

已设置主 App 组件来处理 Bar (来自react-chartjs-2)和 Button 组件 . state 引用要用于 Bar 的数据对象,变量 updated 用于确定要在 handleUpdate() 方法中显示的数据 .

当单击 Button 时,它应该调用 App 中的 handleUpdate() 方法,该方法作为 onClick 在props中的参考传递 . 该方法评估 updated 并使用 setState() 来更改正在使用的数据 . 我正在使用 setState() 的回调来记录状态并更改 updated 的值 .

import React from 'react';
    import ReactDOM from 'react-dom';
    import { Bar } from 'react-chartjs-2';

    const chart1 = {
      labels: ['Team1', 'Team2', 'Team3', 'Team4', 'Team5'],
      datasets: [{
        label: 'Team points',
        data: [503, 385, 270, 133, 65],
        backgroundColor: [
          '#4DB6AC',
          '#E57373',
          '#7986CB',
          '#F06292',
          '#E0E0E0'
        ]
      }]
    };

    const chart2 = {
      labels: ['Team1', 'Team2', 'Team3', 'Team4', 'Team5'],
      datasets: [{
        label: 'Team points 2',
        data: [303, 185, 470, 313, 65],
        backgroundColor: [
          '#4DB6AC',
          '#E57373',
          '#7986CB',
          '#F06292',
          '#E0E0E0'
        ]
      }]
    };

    class App extends React.Component {
      constructor(props) {
        super(props);

        this.handleUpdate = this.handleUpdate.bind(this);

        this.updated = false;

        this.state = {
          chartData: chart1
        }

        console.log(this.state.chartData);
        console.log(this.updated);
      }

      // Toggle between chart1 and chart2 based on value of updated
      handleUpdate() {

        if (!this.updated) {
          this.setState({
            chartData: chart2
          }, () => {
            console.log(this.state.chartData);
            this.updated = true;
          });
        }
        else {
          this.setState({
            chartData: chart1
          }, () => {
            console.log(this.state.chartData);
            this.updated = false;
          });
        }
      }

      render() {
        return(
          <div>
            <Bar data={this.state.chartData} width={650} height={400} />
            <Button handleOnClick={this.handleUpdate} />
          </div>
        );
      }
    }

    const Button = (props) => (
        <button id="update-chart" onClick={props.handleOnClick}>Update</button>
    );

    ReactDOM.render(
      <App />,
      document.getElementById('chart-container')
    );

第一次单击按钮时,一切都按预期工作,状态更新,组件重新呈现以显示新数据 . 但是,在后续单击时,状态保持不变,并且图表继续引用相同的数据 .

console output - 第一个对象是初始渲染,单击按钮后记录后续两个 . 如您所见,数据确实在第一个按钮单击时发生更改,但不会在第二个或任何后续单击时发生更改 .

我知道 setState() 是异步的,可能是批量更新,但我没有改变 .

edit :我认为这个问题与react-chartjs-2有关 . 如果我删除 import 语句以导入 Bar 组件,而是将 Bar 定义为与Chartjs无关的常规函数组件,则 App 的状态在每次单击时在两个数据对象之间成功更改 .

所以它似乎与将数据道具从react-chartjs-2传递到 Bar 组件有关 . 虽然我不确定为什么会阻止 App 的状态发生变化,因为它是顶级组件 .

Here is a JSFiddle显示了不使用 Bar 作为react-chartjs-2组件时的工作原理 .

1 回答

  • 0

    我希望我可以将其用作评论,但我正在重新创建您拥有的内容并且无法复制您的错误 . 你的代码难以解释,这可能会让我/我们失望 . 这是我对你的实施 handleUpdate

    const chartData = this.updated ? chart2 : chart1
    this.setState({chartData}, () => {
      this.updated = this.updated ? false : true
    })
    

相关问题