React ChartJS会阻止新数据在重绘后添加到状态中吗?

Cur*_*s13 5 reactjs chart.js react-chartjs react-state-management

我正在尝试使用react-chartjs-2更新我的图表.我正在使用日期选择器来过滤不同的数据并相应地重新渲染图表,例如今天,昨天,过去7天等显示数据.数据是从我的数据库中提取的

但是,当图表被重新绘制并重新渲染时,它会被添加到我不想要的状态.我只想重新渲染请求重新渲染的新数据,并添加到图表中的旧数据中.

我之前使用vanilla JavaScript修复了这个问题,因为我没有使用反应我使用destroy()了图表文档说使用的方法,但我不确定如何使用它与反应?

因此,经过进一步检查,我的图表似乎正在重新渲染.但是,当它被重新渲染时,额外的数据被添加到我不想要的我的chartData状态,我只是想要请求的新数据显示在图表上.我还在努力想出那个部分.

这是我的代码我有很多,所以我只会显示相关的部分:

import React from "react";

import reportsService from "../../services/reportsService";
import update from "react-addons-update";
import moment from "moment";

import { Bar } from "react-chartjs-2";
import "chartjs-plugin-labels";
import "chartjs-plugin-datalabels";

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

    this.state = {
      chartData: {
        labels: [],
        datasets: [
          {
            //label: "Quotes",
            data: [],
            backgroundColor: []
          }
        ]
      }
    };
  }

  chartColors() {
    let colors = [];
    for (let i = 0; i < 100; i++) {
      let r = Math.floor(Math.random() * 200);
      let g = Math.floor(Math.random() * 200);
      let b = Math.floor(Math.random() * 200);
      let c = "rgb(" + r + ", " + g + ", " + b + ")";
      colors.push(c);
    }

    // Update deep nested array of objects in state
    this.setState({
      chartData: update(this.state.chartData, {
        datasets: { 0: { backgroundColor: { $set: colors } } }
      })
    });
  }

  datePicker() {
    let _this = this;
    let start = moment().subtract(29, "days");
    let end = moment();
    let showReports;
    let data;
    let reloNames = [];
    let reloCount = [];

    function focusDate(start, end) {
      $("#daterangePicker span").html(
        start.format("MMMM D, YYYY") + " - " + end.format("MMMM D, YYYY")
      );
    }

    $("#daterangePicker").daterangepicker(
      {
        startDate: start,
        endDate: end,
        ranges: {
          Today: [moment(), moment()],
          Yesterday: [
            moment().subtract(1, "days"),
            moment().subtract(1, "days")
          ],
          "Last 7 Days": [moment().subtract(6, "days"), moment()],
          "Last 30 Days": [moment().subtract(29, "days"), moment()],
          "This Month": [moment().startOf("month"), moment().endOf("month")],
          "Last Month": [
            moment()
              .subtract(1, "month")
              .startOf("month"),
            moment()
              .subtract(1, "month")
              .endOf("month")
          ]
        }
      },
      focusDate
    );

    focusDate(start, end);

    $("#daterangePicker").on("apply.daterangepicker", async function(
      event,
      picker
    ) {
      switch (picker.chosenLabel) {
        case "Today":
          showReports = await reportsService.reloQuotes({
            reportStatus: "Today"
          });

          data = showReports.recordsets[0];

          data.forEach((element, index, array) => {
            reloNames.push(element.reloNames);
            reloCount.push(element.NoofOrders);
          });

          _this.setState({
            chartData: update(_this.state.chartData, {
              labels: { $set: reloNames },
              datasets: { 0: { data: { $set: reloCount } } }
            })
          });

          console.log(_this.state);

          break;
        case "Yesterday":
          showReports = await reportsService.reloQuotes({
            reportStatus: "Yesterday"
          });

          data = showReports.recordsets[0];

          data.forEach((element, index, array) => {
            reloNames.push(element.reloNames);
            reloCount.push(element.NoofOrders);
          });

          _this.setState({
            chartData: update(_this.state.chartData, {
              labels: { $set: reloNames },
              datasets: { 0: { data: { $set: reloCount } } }
            })
          });

          console.log(_this.state);

          break;
        case "Last 7 Days":
          showReports = await reportsService.reloQuotes({
            reportStatus: "Last 7 Days"
          });

          data = showReports.recordsets[0];

          data.forEach((element, index, array) => {
            reloNames.push(element.reloNames);
            reloCount.push(element.NoofOrders);
          });

          _this.setState({
            chartData: update(_this.state.chartData, {
              labels: { $set: reloNames },
              datasets: { 0: { data: { $set: reloCount } } }
            })
          });

          console.log(_this.state);

          break;
      }
    });

    //console.log(this.state);
  }

  async reloQuotes() {
    const showreloQuotes = await reportsService.reloQuotes();
    let data = showreloQuotes.recordsets[0];
    let reloNames = [];
    let reloCount = [];

    data.forEach((element, index, array) => {
      reloNames.push(element.reloNames);
      reloCount.push(element.NoofOrders);
    });

    this.setState({
      chartData: update(this.state.chartData, {
        labels: { $set: reloNames },
        datasets: { 0: { data: { $set: reloCount } } }
      })
    });
  }

  async componentDidMount() {
    await this.chartColors();
    await this.datePicker();

    // Execute models real time thus re-rendering live data on the chart real time
    await this.reloQuotes();
  }

  render() {
    return (
      <div className="fluid-container">
        <div className="container">
          <h1>Reports</h1>
          <div className="row">
            <div className="daterangeContainer">
              <div
                id="daterangePicker"
                style={{
                  background: "#fff",
                  cursor: "pointer",
                  padding: "5px 10px",
                  border: "1px solid #ccc",
                  width: "100%"
                }}
              >
                <i className="fa fa-calendar" />
                &nbsp;
                <span /> <i className="fa fa-caret-down" />
              </div>
            </div>
          </div>
          <div className="row">
            <div className="col-md-12">
              <Bar
                data={this.state.chartData}
                height={800}
                options={{
                  maintainAspectRatio: false,
                  legend: {
                    display: false
                  },
                  scales: {
                    xAxes: [
                      {
                        ticks: {
                          beginAtZero: true,
                          autoSkip: false
                        },
                        scaleLabel: {
                          display: true
                        }
                      }
                    ]
                  },
                  title: {
                    display: true,
                    text: "Quotes",
                    fontSize: 16
                  },
                  plugins: {
                    datalabels: {
                      display: true,
                      color: "white"
                    }
                  }
                }}
                redraw
              />
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default Reportspage;
Run Code Online (Sandbox Code Playgroud)

pgs*_*rom 2

因此,您描述的问题是,当组件重新渲染时,数据会添加到组件状态中。在您提供的代码片段中,您没有使用 React 中任何可以在重新渲染时触发的生命周期方法。我看不到任何其他应该在重新渲染时触发的钩子。因此我找不到你的问题的任何根源。

但是,我发现其他问题可能会使您的调试变得更加困难。解决这些问题可能会帮助您解决实际问题。在该componentDidMount方法中,您调用其唯一目的是更新状态的函数。这不是一个好的设计,因为它会迫使组件在安装时立即重新渲染多次。

更好的设计是在构造函数中充分准备图表数据对象。例如,您可以更改chartColors函数以将图表数据对象作为参数,并返回添加了颜色的新对象。然后让你的构造函数看起来像这样:

constructor(props) {

   super(props);
   const chartDataWithoutColors = {
       labels: [],
       datasets: [
         {
           //label: "Quotes",
           data: [],
           backgroundColor: []
         }
       ]
     }

   const chartDataWithColor = this.chartColors(chartDataWithoutColors);

   this.state = {
     chartData: chartDataWithColor
   };
}
Run Code Online (Sandbox Code Playgroud)

通过删除不必要的调用,setState您的组件生活将变得更简单、更高效。当您简化了组件后,请通过一次删除一个非关键部分来开始调试,并尝试在问题消失时确定下来。这应该足以找到错误。

祝你好运!