以间隔反应 ApexCharts 更新图表

React ApexCharts update chart with interval

我正在构建一个 React 应用程序,它将显示一些需要从 api 调用中不断更新的图表(使用 ApexCharts)。他们将显示来自不同来源的传感器数据。

我已根据需要对图表进行样式设置和配置,但如果我通过更改 setInterval 表达式中的状态数组来更新数据,则在几次迭代后图表开始表现异常,就像同时存在冲突更新。

这是CodeSandBox中的App.js文件:

//App.js
export default function App() {
  const [data, updateData] = useState([1, 2, 3, 4, 5, 6]);

  useEffect(() => {
    setInterval(() => {
      const val = Math.floor(Math.random() * (100 - 30 + 1)) + 30;
      let array = [...data, val];
      array.shift();
      updateData(array);
    }, 2000);
  });
  return (
    <div className="App">
      <ChartViewer data={data} title="Product Trends by Month" />
    </div>
  );
}

这是 ChartViewer 组件:

import Chart from "react-apexcharts";

export default function ApexChart(props) {
  const series = [
    {
      name: "xx",
      data: props.data
    }
  ];
  const options = {
    chart: {
      height: 350,
      type: "line",
      zoom: {
        enabled: true
      }
    },
    dataLabels: {
      enabled: false
    },
    stroke: {
      width: 2,
      curve: "smooth"
    },
    colors: ["#210124"],
    fill: {
      type: "gradient",
      gradient: {
        shadeIntensity: 1,
        inverseColors: true,
        gradientToColors: ["#DB162F"],
        opacityFrom: 1,
        opacityTo: 1,
        type: "vertical",
        stops: [0, 30]
      }
    }
  }
  return (
    <div id="chart">
      <Chart options={options} series={series} type="line" height={350} />
    </div>
  );
}

此外,这里是 CodeSandbox Link,您可以在其中查看行为:https://codesandbox.io/s/purple-monad-5c1i3?file=/src/ChartViewer.js:41-839

提前致谢

您没有将依赖项传递给 useEffect。这使得它在每次渲染时 运行 使您的图表经常重绘。

要解决此问题,您必须稍微更改一下 useEffect:

  useEffect(() => {
    const interval = setInterval(() => {
      const val = Math.floor(Math.random() * (100 - 30 + 1)) + 30;
      let array = [...data, val];
      array.shift();
      updateData(array);
    }, 2000);
    return () => {
      window.clearInterval(interval); // clear the interval in the cleanup function
    };
  }, [data]); // pass the data as a dependency (because you are using it inside the effect)

您可以在此处查看更新后的行为:https://codesandbox.io/s/pedantic-mendeleev-tx5ck

您忘记将空数组作为 useEffect 挂钩的第二个参数:

它正在运行。试试这个代码:

import React, { useState, useEffect } from "react";
import "./styles.css";
import ChartViewer from "./ChartViewer";

export default function App() {
  const [data, updateData] = useState([1, 2, 3, 4, 5, 6]);

  useEffect(() => {
    setInterval(() => {
      const val = Math.floor(Math.random() * (100 - 30 + 1)) + 30;
      let array = [...data, val];
      console.log(array);
      array.shift();
      updateData(array);
    }, 2000);
  }, []);
  return (
    <div className="App">
      <ChartViewer data={data} title="Product Trends by Month" />
    </div>
  );
}

这是工作沙箱:https://codesandbox.io/s/peaceful-fire-fdw98

卸载此组件时不要忘记清除 setInterval API 调用。

谢谢