【发布时间】:2016-04-14 22:11:57
【问题描述】:
我看到一个在 React 组件中使用第三方库的尴尬错误。我能够为这篇文章重现一个人为的演示。
首先让我解释一下我正在使用 c3js - 这是一个图表库,并在 componentDidMount() 中呈现它并在 componentWillUnmount() 中删除它,并正确调用 this.chart.destroy()。
错误发生在过滤组件本身时,本质上是组件被正确过滤,但位于组件内部的实际图表与第一个图表保持一致,这是非常奇怪的行为。基本上是错误组件内的错误图表!
您可以通过单击Remove all charts except chart 3 按钮了解我的意思,我已用chartid 标记图表,过滤将正确删除其他图表。
我相当肯定这不是我的代码,因为过滤工作正常并更新了视图。您可以验证,因为我已经标记了图表并且它在视图中可见。没有控制台错误,我已经验证了我的代码可以正常工作。
所以我的问题是 - 我们可以使用 c3js 解决这个限制吗,或者这真的是我的代码和我呈现图表的方式的问题。
相关演示:https://jsfiddle.net/69z2wepo/38614/
相关代码:
var data = [
{
chartid: 1,
columns: [
['x', 0, 1, 2, 3, 4, 5, 6],
['data1', 130, 300, 330, 400, 300, 400, 500],
['data2', 390, 230, 200, 150, 100, 130, 210],
['data3', 290, 430, 300, 160, 210, 170, 190],
['data4', 190, 330, 200, 260, 190, 250, 320]
]
},
{
chartid: 2,
columns: [
['x', 0, 1, 2, 3, 4, 5, 6],
['data1', 130, 300, 330, 400, 300, 400, 500],
['data2', 390, 230, 200, 150, 100, 130, 210],
['data3', 290, 430, 300, 160, 210, 170, 190]
]
},
{
chartid: 3,
columns: [
['x', 0, 1, 2, 3, 4, 5, 6],
['data1', 130, 300, 330, 400, 300, 400, 500],
['data2', 390, 230, 200, 150, 100, 130, 210]
]
}
];
var Button = React.createClass({
handleDelete: function (id) {
this.props.handleDelete(id);
},
render: function() {
return (
<button onClick={this.handleDelete.bind(null, 3)}>
Remove all charts except chart 3
</button>
)
}
});
var Chart = React.createClass({
componentDidMount() {
this.chart = c3.generate({
bindto: '.chart-' + this.props.data.chartid,
data: {
columns: this.props.data.columns
}
});
},
componentWillUnmount() {
this.chart.destroy();
},
render: function() {
return (
<div>
<h4>{"chart-" + this.props.data.chartid}</h4>
<div className={"chart-" + this.props.data.chartid}>
</div>
</div>
)
}
});
var Child = React.createClass({
renderCharts: function(data) {
return data.map(function(metrics, i) {
return (
<Chart key={i} data={metrics} />
)
});
},
handleDelete: function(id) {
this.props.handleDelete(id);
},
render: function() {
return (
<div>
<Button handleDelete={this.handleDelete} />
{this.renderCharts(this.props.data)}
</div>
)
}
})
var App = React.createClass({
getInitialState: function() {
return {
initialData: this.props.data
}
},
handleDelete: function(id) {
var _filterFunc = function(data) {
if (data.chartid == id) return true;
return false;
};
var _filterCharts = Array.prototype.filter.call(this.state.initialData, _filterFunc);
this.setState({
initialData: _filterCharts
})
},
render: function() {
return (
<div>
<Child handleDelete={this.handleDelete} data={this.state.initialData} />
</div>
);
}
});
ReactDOM.render(
<App data={data} />,
document.getElementById('container')
);
【问题讨论】:
标签: javascript reactjs charts c3.js