最近项目用到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,虽说不是很棒的解决方案,但是是我目前找到最简单的解决办法!