React.js处理第三方库安装
React.js handling 3rd party library mounting
我看到一个使用react组件内部的第三方库的尴尬错误。我能够为这篇文章复制一个人为的演示。
让我首先解释一下,我使用的是c3js,这是一个图表库,并在componentDidMount()
中呈现它,然后通过对this.chart.destroy()
的正确调用在componentWillUnmount()
中删除它。
错误发生在过滤组件本身时,本质上是组件被正确过滤,但组件内部的实际图表与第一个图表保持不变,这是非常奇怪的行为。基本上是错误的图表在错误的组件中
你可以通过点击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')
);
问题在于您在图表上设置键的方式。这会导致渲染器对您要保留的图表感到困惑。
试试这个:<Chart key={data[i].chartid} data={metrics} />
而不是<Chart key={i} data={metrics} />
看看React是如何处理密钥的。请记住,您使用组件生命周期的密钥来唯一标识子级。因此,由于图表1是由键"1"唯一标识的,因此无法用键"1)呈现图表3。我上面的解决方案确保了图表是由其图表id而不是其呈现顺序唯一标识的。
- 可以前端maven插件使用节点,npm已经安装
- 在Meteor项目中安装并包含npm模块后出错
- 与运行长作业(javascript,node.js)的第三方API同步的最佳实践
- 无法安装节点sass相关性
- 如何检测第三方广告服务器请求
- 键入环境安装不起作用
- 全局安装gull后出错
- 如何检测安装在firefox4.6ubuntu上的扩展
- 将下载链接从web浏览器传递给第三方应用程序
- 在iOS和Android上使用React native时,我还能使用本机第三方lirbraries吗
- Bowerrc后安装挂钩不工作
- 有没有一种方法可以从Javascript检测特定的应用程序是否安装在(AndroidiOS)设备上
- 如何安装Jasmin:Velocity项目上的javascript测试工具
- 使用jquery cookie的第三方cookie
- markrwithlabel.js(第三方)原始文件链接断开
- 开发第三方小部件-Angular vs jQuery vs普通的旧JS
- 处理第三方库发送的ajax请求的开始和结束事件
- 如何从mac上完全删除Ionic和Cordova安装
- React.js处理第三方库安装
- 检查用户是否安装了第三方Chrome扩展