简体   繁体   English

重新加载反应中的图表数据作为道具数据传递

[英]Reload chart data in react passed as prop data

Hello I'm trying to reload data passed as prop data in a react component.您好,我正在尝试重新加载在反应组件中作为道具数据传递的数据。 I'm using Lightweight Charts library for the charts.我正在为图表使用轻量级图表库。 But I don't think its has something to do with the library itself except of lacking documenation for reloading chart data.但我认为除了缺少重新加载图表数据的文档外,它与库本身没有任何关系。 My react code for the specific component looks like this:我对特定组件的反应代码如下所示:

import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import { createChart, CrosshairMode } from 'lightweight-charts';


export function ChartComponent(props) {
    const chartContainerRef = useRef();
    const chart = useRef();
    const resizeObserver = useRef();
    const candleSeriesRef = useRef();

    useEffect(() => {

      chart.current = createChart(chartContainerRef.current, {
        width: chartContainerRef.current.clientWidth,
        height: chartContainerRef.current.clientHeight,
        layout: {
          backgroundColor: '#253248',
          textColor: 'rgba(255, 255, 255, 0.9)',
        },
        grid: {
          vertLines: {
            color: '#334158',
          },
          horzLines: {
            color: '#334158',
          },
        },
        crosshair: {
          mode: CrosshairMode.Normal,
        },
        priceScale: {
          borderColor: '#485c7b',
        },
        timeScale: {
          borderColor: '#485c7b',
        },
      });
  
      candleSeriesRef.current = chart.current.addCandlestickSeries({
        upColor: '#4bffb5',
        downColor: '#ff4976',
        borderDownColor: '#ff4976',
        borderUpColor: '#4bffb5',
        wickDownColor: '#838ca1',
        wickUpColor: '#838ca1',
      });
  
      candleSeriesRef.current.setData(props.data);
    }, []);
  

  return (
    <div ref={chartContainerRef} className="chart-container" />
  );
}

Component usage:组件使用:

    {/* Chart */}
    <Grid item xs={12}>
      <Paper className={fixedHeightPaper}>
        <ChartComponent data={data}/>
      </Paper>
    </Grid>

When I change the data from the parent view the data is not changing.当我从父视图更改数据时,数据没有更改。 I also tried to call the component useEffect without the last brackets so it gets called every time the props change but then I'm just stacking new charts under the original one.我还尝试在没有最后一个括号的情况下调用组件 useEffect,因此每次道具更改时都会调用它,但随后我只是在原始图表下堆叠新图表。 What I want to achieve is to just change the whole data from parent side and reload the chart.我想要实现的是从父端更改整个数据并重新加载图表。

First: Understanding react hooks第一:了解 React Hooks

useEffect react hook let you perfom an action when a prop/DOM mount/DOM unmount or state changes, so useEffect react hook 让你在 prop/DOM mount/DOM unmount 或 state 改变时执行一个动作,所以

useEffect(() => {
    //this function will be called every time data prop changes
    return () => {
        //this function will be called after the above function finishes.
        //here you can do cleanup.
    }
},[props.data]) //this array is for all the dependencies/values to watch.

useEffect hook calls the function depending on what is on dependencies, useEffect 挂钩根据依赖项调用 function,

[]           = function will be called on mount and cleanup on unmount
[some value] = function will be called on mount and only when the value changes
no value     = function will be called on every render

Second: Solution第二:解决方案

import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import { createChart, CrosshairMode } from 'lightweight-charts';


export function ChartComponent(props) {
    const chartContainerRef = useRef();
    const chart = useRef();
    const resizeObserver = useRef();
    const candleSeriesRef = useRef();

    useEffect(() => {

      chart.current = createChart(chartContainerRef.current, {
        width: chartContainerRef.current.clientWidth,
        height: chartContainerRef.current.clientHeight,
        layout: {
          backgroundColor: '#253248',
          textColor: 'rgba(255, 255, 255, 0.9)',
        },
        grid: {
          vertLines: {
            color: '#334158',
          },
          horzLines: {
            color: '#334158',
          },
        },
        crosshair: {
          mode: CrosshairMode.Normal,
        },
        priceScale: {
          borderColor: '#485c7b',
        },
        timeScale: {
          borderColor: '#485c7b',
        },
      });
  
      candleSeriesRef.current = chart.current.addCandlestickSeries({
        upColor: '#4bffb5',
        downColor: '#ff4976',
        borderDownColor: '#ff4976',
        borderUpColor: '#4bffb5',
        wickDownColor: '#838ca1',
        wickUpColor: '#838ca1',
      });
  
      candleSeriesRef.current.setData(props.data);
    }, [props.data]);
  

  return (
    <div ref={chartContainerRef} className="chart-container" />
  );
}

Third: improved solution第三:改进方案

Recreating chart every time data prop change is too expensive.每次数据属性更改时都重新创建图表太昂贵了。

import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import { createChart, CrosshairMode } from 'lightweight-charts';


export function ChartComponent(props) {
    const chartContainerRef = useRef();
    const chart = useRef();
    const resizeObserver = useRef();
    const candleSeriesRef = useRef();
    
    //this effect will be called only once, since there is no dependencies.
    useEffect(() => {

      chart.current = createChart(chartContainerRef.current, {
        width: chartContainerRef.current.clientWidth,
        height: chartContainerRef.current.clientHeight,
        layout: {
          backgroundColor: '#253248',
          textColor: 'rgba(255, 255, 255, 0.9)',
        },
        grid: {
          vertLines: {
            color: '#334158',
          },
          horzLines: {
            color: '#334158',
          },
        },
        crosshair: {
          mode: CrosshairMode.Normal,
        },
        priceScale: {
          borderColor: '#485c7b',
        },
        timeScale: {
          borderColor: '#485c7b',
        },
      });
  
      candleSeriesRef.current = chart.current.addCandlestickSeries({
        upColor: '#4bffb5',
        downColor: '#ff4976',
        borderDownColor: '#ff4976',
        borderUpColor: '#4bffb5',
        wickDownColor: '#838ca1',
        wickUpColor: '#838ca1',
      });
    }, []);
    
    //this effect will be called every time data props changes
    useEffect(() => {
      if(chart.current)
      candleSeriesRef.current.setData(props.data);
    }, [props.data]);
  

  return (
    <div ref={chartContainerRef} className="chart-container" />
  );
}

reactjs docs explains it better, https://reactjs.org/docs/hooks-effect.html reactjs 文档解释得更好, https://reactjs.org/docs/hooks-effect.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM