2019-01-24
Highcharts
React 中使用 Highcharts
在 React 中使用 Highcharts 可以采用 react-highcharts 这个库。它的一般用法如下:
00<ReactHighcharts
01    config={{ 
02        /* Highcharts 的配置 */
03}} />
一般的需求用它就够了,但是某些组件重绘的场景需要特别注意,它是这么说的:
Rerendering a highcharts graph is expensive. You can pass in a isPureConfig option to the ReactHighcharts component, which will keep the highcharts graph from being updated so long as the provided config is referentially equal to its previous value. There is also neverReflow property.
打一是说,重绘比较耗性能,因此我们可以传入 isPureConfig 来控制:传入了 true 之后,它会做 config引用判断 来判断要不要重绘,此外它还提供了一个 nerverReflow 的选项,这个是用来禁用重绘的。
对的,引用判断,就是判断 newConfig 跟 config 是不是相等的,好比:
00{} === {}
一般来说够用了,只是在用纯 Hooks 做的 React 应用里就有点蛋疼了。

# 自己实现

写这篇文章的目的不是介绍这个库,而是这个东西怎么实现的 233
技术栈:React Hooks TypeScript Highcharts

# 具体实现

00// Charts.tsx 
01import * as React from "react"; 
02
03import * as Highcharts from "highcharts";
04
05// Props Of <Charts />
06export type ChartsProps = {
07    renderId: string | number, 
08    option: Highcharts.Options
09}
10
11// Charts Container 
12export function Charts(props: ChartsProps) {
13    // Default
14    const [renderId, setRenderId] = React.useState(props.renderId);
15
16    // Set New One For Rerender 
17    if (props.renderId !== renderId) {
18        setRenderId(props.renderId); 
19    }
20
21    // Dom Reference 
22    const $div = React.useRef(null);
23    
24    // A Trick To Implement Conditional Rerender 
25    React.useEffect(() => {
26        const config = getChartsData(items, list);
27        config && HightChart.chart($div.current, config);        
28    }, [ renderId ])
29
30    return (
31        <div ref={ $div } ></div>
32    );
33}

# 使用方法

00// App.tsx 
01import * as React from "react"; 
02import { Charts } from "./Charts";
03import { fetchData, processToOption } from "./path/to/utils";
04
05export function App() {
06    const [renderId, setRenderId] = React.useState(0);
07    const [option, setOption] = React.useState(null);
08    
09    // Click -> fetchData -> Option -> Set Option -> Rerender  
10    const update = () => fecthData()
11        .then(processToOption)
12        .then(setOption); 
13    
14    return (
15        <div>
16            <Charts renderId={ renderId } />
17            
18            {/* Updating When Clicking */}
19            <button onClick={ update }>Fetch New Data</button>
20        </div>
21    );
22}

# 说明

  1. 利用 useEffect 来隔离副作用
  2. 引入 renderId 来控制重绘, renderId 变了就重绘
  3. 利用 setState 和 useEffect 来触发重绘
Hooks 带来的变革不仅仅是 useState 这个比较明显的变化,它带来的变革还包括状态分发、副作用控制等世界性难题,有机会我再写写 Context Hooks 相关的 API。




回到顶部