当 apiData 保持不变时,React 图表不会更新

问题描述 投票:0回答:1

我正在开发一个使用react-chartjs-2显示折线图的React组件。每当从 API 收到新数据 (apiData) 时,图表都应更新。我面临的问题是,如果新的 apiData 值与前一个值相同,则图表不会更新或重新渲染。

这是我组件的相关部分:

import React, { useState, useContext, useEffect } from 'react';
import { Line } from 'react-chartjs-2';
import { DataContext } from '../../context/DataContext';
import 'chart.js/auto';
import styled from 'styled-components';

const MAX_DATA_POINTS = 100;

const Container = styled.div`
    width: 99%;
    height: 100%;
`;

const Graph = ({ apiData, graphLabel }) => {
    const { streaming, clearFlag, setClearFlag } = useContext(DataContext);

    const [graphData, setGraphData] = useState(() => {
        const storedData = sessionStorage.getItem('graphData');
        return storedData ? JSON.parse(storedData) : [];
    });

    const [key, setKey] = useState(0); // new state to track re-renders

    useEffect(() => {
        if (streaming) {
            setGraphData(prevData => {
                const newData = [
                    ...prevData,
                    { time: new Date().toLocaleTimeString(), data: apiData }
                ];
                // Limit the number of data points to preserve interval
                if(newData.length > MAX_DATA_POINTS){
                    newData.shift();
                }

                sessionStorage.setItem('graphData', JSON.stringify(newData));
                setKey(prevKey => prevKey + 1); // trigger re-render
                return [...newData]; // return new array to trigger re-render 
            });
        }
    }, [apiData, streaming]);

    const dataPoints = {
        labels: graphData.map(d => d.time),
        datasets: [
            {
                label: graphLabel,
                data: graphData.map(d => d.data),
                fill: false,
                backgroundColor: '#F3F4F6',
                borderColor: '#0077C8',
            },
        ],
    };

    useEffect(() => {
        if (clearFlag) {
            setGraphData([]);
            sessionStorage.removeItem('graphData');
            setClearFlag(false);
        }
    }, [clearFlag])

    const options = {
        scales: {
            y: {
                beginAtZero: true,
                max: 1000,
            },
        },
        maintainAspectRatio: false,
        animation: {
            duration: 0,
        },
        plugins: {
            legend: {
                labels: {
                    font: {
                        size: 18,
                        weight: 'bold',
                    },
                    color: 'black'
                }
            }
        }
    };

    return (
        <Container>
            <Line data={dataPoints} options={options} />
        </Container>
    );
};

export default Graph;
javascript reactjs charts
1个回答
0
投票

我只是添加一个时间戳来比较并触发重新渲染。

useEffect(() => {
        if (streaming && apiData !== null) {
            setGraphData(prevData => {
                const newData = [
                    ...prevData,
                    { time: new Date().toLocaleTimeString(), data: apiData }
                ];
                // Limit the number of data points to preserve interval
                if(newData.length > MAX_DATA_POINTS){
                    newData.shift();
                }

                sessionStorage.setItem('graphData', JSON.stringify(newData));
                return [...newData]; // return new array to trigger re-render
            });
        }
    }, [apiData, timestamp, streaming]);

再次感谢 stackoverflow。

© www.soinside.com 2019 - 2024. All rights reserved.