【问题标题】:react-chartjs state update errorreact-chartjs状态更新错误
【发布时间】:2017-10-15 13:44:32
【问题描述】:

我制作了一个 React.JS 组件,它使用 react-chartjs 包装器围绕 chart.js 库绘制图表。我在更新时遇到错误,好像我的数据已损坏。我在想可能是上下文有问题,也许是因为我没有看到我的代码有任何问题。第一次绘制图表时,它显示得很好。 setState 原因:Uncaught Type Error: Cannot read property 'points' of undefined(...) 发生在 core.js 内部 set.data.forEach() 的匿名函数中。 以下是我的代码:

class Usage extends Component {

  constructor(props) {
    super(props);
    this.state = {
      active: true,
      new: false,
      chartData: []
    }
  }

  componentWillMount() {
    this.buildChartData();
  }

buildChartData() {
    const daysInMonth = 30;
    const graphs = [
      {title: 'Active Users', key: 'active', color: 'rgba(255, 99, 132, 1)'}, 
      {title: 'New Users', key: 'new', color: 'rgba(50, 25, 255, 1)'}
    ];
    let datasets = [];
    let labels = [];
    let labelsDone = false;

    graphs.forEach((graph) => {

      if (this.state[graph.key]) {
        let data = [];
        let backgroundColor = [];
        let borderColor = [];

        // XXX !!! for now
        if (!labelsDone) {
          for (let i = daysInMonth; i > 0; i--) {
            let d = new Date();
            // we stop yesterday
            d.setDate(d.getDate() - i);
            labels.push( (d.getUTCMonth() + 1) + '/' + d.getUTCDate() );
          }
        }
        labelsDone = true;

        for (let i = daysInMonth; i > 0; i--) {
          let d = new Date();
          // we stop yesterday
          d.setDate(d.getDate() - i);
          data.push( Math.round(Math.random() * 200));
          borderColor.push(graph.color);
          backgroundColor.push('rgba(0,0,0,0)');
        }
        let dataset = {
          data: data, 
          borderWidth: 1, 
          label: graph.title,
          fillColor: 'rgba(0,0,0,0.0)',
          strokeColor: borderColor
        };
        datasets.push(dataset);
      }
    })
    this.setState({
      chartData: {datasets: datasets, labels: labels}
    });
  }

  toggleCheckbox = label => {
    switch(label) {
      case 'Active Users':
        this.setState({
          active: !this.state.active
        });
        break;
      case 'New Users':
        this.setState({
          new: !this.state.new
        });
        break;
      default:
        console.log('Error: unhandled action');
        break;
    }
    this.buildChartData();
  }

  render() {
    return (
        <div style={{display: 'flex', flexDirection: 'row'}}>
          <div style={{flexDirection: 'column', marginLeft: '50px', marginRight: '50px', flexGrow: 1}}>
            <div style={{height: '20vh'}}>
              <div style={{flexDirection: 'row'}}>
                <Checkbox
                  label={'Active Users'}
                  handleCheckboxChange={this.toggleCheckbox}
                  isChecked={true}
                />
                <Checkbox
                  label={'New Users'}
                  handleCheckboxChange={this.toggleCheckbox}
                  isChecked={false}
                />
              </div>
            </div>
            <div style={{height: '75vh'}}>
              <Line data={this.state.chartData} options={chartOptions} />
            </div>
          </div>
        </div>
      );
  }
}

export default Usage;

我打印了较小的数据集,其中发生了同样的事情。除了随机生成的值之外,看不到任何差异。尽管如此,初始渲染还不错,但 setState,据我所知,调用 update 会导致上述错误。

【问题讨论】:

  • 积分从何而来?
  • 好问题。请尝试代码。也许你可以弄清楚并告诉我。
  • 能把core.js的代码也发一下吗?
  • 当然,$npm install react-chartjs
  • @MosheShmukler 如果你正在使用,babel-loader 尝试添加 exclude: /(node_modules)/, 作为排除项。

标签: javascript reactjs chart.js react-chartjs


【解决方案1】:

如果传递到组件的数据发生变化,点将使用 chart.js 的 .update() 在值之间进行动画处理。如果您希望图表在每次更改时都被销毁并重绘,请将 redraw 作为道具传入。例如&lt;LineChart data={this.state.chartData} redraw /&gt;

添加redraw 即可解决问题。

【讨论】:

  • 它可能会解决问题,但是当toggleCheckbox 被触发时 2 setState 会发生,这将强制重新渲染两次。如果您编写一个函数来根据切换键返回所需键的数据集并将其传递给 Chart JS 组件,而不是强制执行 2 次渲染,这是性能瓶颈,特别是因为 Chart JS 使用画布渲染图表会更好跨度>
  • 你太棒了。
猜你喜欢
  • 2018-08-25
  • 1970-01-01
  • 2018-10-03
  • 2023-02-11
  • 2020-08-09
  • 2018-07-01
  • 1970-01-01
  • 2015-06-11
  • 1970-01-01
相关资源
最近更新 更多