最近項目用到Echarts(以下用ec代替),於是照貓畫虎得引入到團隊的antd項目中,但是遇到2個棘手問題:
1. ec對dom不渲染,檢查后發現,原來是全局存在id重復,所以使用React時,最好對使用id保持全局唯一,說個題外話,其實 會用到id的機會少之又少。
2. ec報錯:Cannot read property 'getAttribute' of null ,因為ec需要一個渲染掛載點,而用getById時,總是獲取不到。
3.Component series.scatter not exists. Load it first. 是echart的引入問題
先說一下需求,我要實現點擊按鈕彈一個框 modal,框里有一個柱形圖,用於展示一些數據,正是由於彈框是需要時才會渲染存在的,因此就會出現找不到該DOM節點的情況,說是ec問題,實際上還是React問題。
網上找了很久,有說用componentDidmount的,有說用 window.onload 的,有說用setTimeout延遲一下再獲取的,可能是我的需求比較刁鑽,統統不行,花了4小時實力踩坑,最后回歸到文檔,終於找到解決辦法了,靈感來源:https://react.docschina.org/docs/refs-and-the-dom.html
解決方案只涉及React提供的東西足夠:ref,無須用到id,window.onload之類的
class CustomTextInput extends React.Component { constructor(props) { super(props); this.textInput = null; this.setTextInputRef = element => { this.textInput = element; }; this.focusTextInput = () => { // 直接使用原生 API 使 text 輸入框獲得焦點 if (this.textInput) this.textInput.focus(); }; } componentDidMount() { // 渲染后文本框自動獲得焦點 this.focusTextInput(); } render() { // 使用 `ref` 的回調將 text 輸入框的 DOM 節點存儲到 React // 實例上(比如 this.textInput) return ( <div> <input type="text" ref={this.setTextInputRef} /> <input type="button" value="Focus the text input" onClick={this.focusTextInput} /> </div> ); } }
我稍微加以改造,呈現如下:
注意:這是modal里的代碼,modal是會被生成或銷毀的,因此需要多次生成圖表
return ( <Modal {...modalOpts}> <Row {...rowProps}> <Col span={24}> <div ref={this.setTextInputRef} style={{ width: '500px', height: '500px' }}></div> </Col> </Row> </Modal> )
setTextInputRef(element) { if (element) { // 基於准備好的dom,初始化echarts實例 const dom = element var myChart = echarts.init(dom) // 繪制圖表 myChart.setOption({ title: { text: 'ECharts 入門示例' }, tooltip: {}, xAxis: { data: ["襯衫", "羊毛衫", "雪紡衫", "褲子", "高跟鞋", "襪子"] }, yAxis: {}, series: [{ name: '銷量', type: 'bar', data: [5, 20, 36, 10, 10, 20] }] }) } };
這里是借用ref,雖說不是很棒的解決方案,但是是我目前找到最簡單的解決辦法!