Highcharts wrapper for React

简介

一个非常精简的包装工具,可以在 React 项目中使用 highcharts

源码分析

服务端渲染的时候 useLayoutEffect 会抛出警告,所以需要按条件使用,如果是浏览器环境使用 useLayoutEffect,如果是服务器环境使用 useEffect

使用 useLayoutEffect 可以保证在布局阶段, ref 所指向的挂载元素是可以使用的,也可以用在一个父组件的 componentDidMount

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

// 区分浏览器环境还是
const useIsomorphicLayoutEffect =
typeof window !== 'undefined' ? useLayoutEffect : useEffect;


// 使用 forwardRef 转发 ref, 将 ref 传递到子组件
// 如果有需要可以通过传入 ref 属性,获取到挂载节点的真是DOM元素
// 也可以配合 useImperativeHandle 使用
const HighchartsReact = forwardRef(
function HighchartsReact(props, ref) {

const containerRef = useRef();
const chartRef = useRef();

useIsomorphicLayoutEffect(() => {
function createChart() {
const H = props.highcharts || (
typeof window === 'object' && window.Highcharts
);

// 暴露参数,用于表明实例化图表类型
const constructorType = props.constructorType || 'chart';

if (!H) {
console.warn('The "highcharts" property was not passed.');

} else if (!H[constructorType]) {
console.warn(
'The "constructorType" property is incorrect or some ' +
'required module is not imported.'
);

// options 必填参数,如果没有提示警告
} else if (!props.options) {
console.warn('The "options" property was not passed.');

} else {
// 创建图表实例
chartRef.current = H[constructorType](
containerRef.current,
props.options,
props.callback ? props.callback : undefined
);
}
}

if (!chartRef.current) {
createChart();
} else {
// 是否允许图表更新,如果为假,在接受到新的 props 之后会直接忽略掉
if (props.allowChartUpdate !== false) {
// immutable 用于指定是否使用不可变数据
// 本质就是不会再原有的图表上更新,而会直接创建新图表的实例
if (!props.immutable && chartRef.current) {
chartRef.current.update(
props.options,
// 与用指定原生的更新参数,由 highcharts 自己提供
...(props.updateArgs || [true, true])
);
} else {
createChart();
}
}
}
});

useIsomorphicLayoutEffect(() => {
return () => {
// 组件卸载的时候注销实例
if (chartRef.current) {
chartRef.current.destroy();
chartRef.current = null;
}
};
}, []);



// 一般配合 forwardRef 使用
// 可以用于暴露封装组件内部的状态
// 通过 ref.current.chart 或 ref.current.chart 可以在外部获取到组件实例,以及挂载节点
useImperativeHandle(
ref,
() => ({
get chart() {
return chartRef.current;
},
container: containerRef
}),
[]
);

// Create container for the chart
return <div { ...props.containerProps } ref={ containerRef } />;
}
);

export default memo(HighchartsReact);
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2025 SunZhiqi

此时无声胜有声!

支付宝
微信