javascript - 在作为道具数据传递的反应中重新加载图表数据
问题描述
您好,我正在尝试重新加载在反应组件中作为道具数据传递的数据。我正在为图表使用轻量级图表库。但我认为它与库本身无关,只是缺少重新加载图表数据的文档。我对特定组件的反应代码如下所示:
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" />
);
}
组件使用:
{/* Chart */}
<Grid item xs={12}>
<Paper className={fixedHeightPaper}>
<ChartComponent data={data}/>
</Paper>
</Grid>
当我从父视图更改数据时,数据没有改变。我还尝试在没有最后一个括号的情况下调用组件 useEffect ,因此每次道具更改时都会调用它,但我只是在原始图表下堆叠新图表。我想要实现的只是从父端更改整个数据并重新加载图表。
解决方案
第一:了解 React Hooks
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 挂钩根据依赖项调用函数,
[] = 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
二:解决方案
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" />
);
}
第三:改进的解决方案
每次数据道具更改时重新创建图表太昂贵了。
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 文档解释得更好,https: //reactjs.org/docs/hooks-effect.html
推荐阅读
- jwt - 客户端到服务之间的 Auth0 流
- oracle - Oracle 中的自定义日期格式
- javascript - 来自 Gsheet 的 html 文件中的 Google Apps 脚本动态表格行
- node.js - 外部 API 调用服务器还是客户端?
- vue.js - Vue-formulate - 分组项目可折叠/切换折叠
- typo3 - 在typo3中维护hreflang外部页面
- node-modules - 如何使用带有动态参数的“google-charts-node”npm 包
- python - 不同 git 存储库中 python 脚本之间的接口
- python - 如何使用 python 在 selenium 中安装特定于本地 chrome 浏览器版本的 chromedriver?
- javascript - 使用 Javascript 解构时,是否有任何简洁的方法可以将默认值设置为 null