使用React ApexCharts定时更新图表

3

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

我已经按照需要对图表进行了样式和配置,但是如果我通过在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 链接,您可以在此查看其行为:https://codesandbox.io/s/purple-monad-5c1i3?file=/src/ChartViewer.js:41-839

提前感谢。

2个回答

2

您没有向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

0

你忘记在 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 调用。
谢谢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接