是的,我知道这里有反应艺术,但似乎已经坏了。
问题在于d3.js只是为了改变浏览器DOM,而直接使用它(例如在componentDidMount方法内部)将无法正常工作,因为对浏览器DOM的所有更改都不会反映在React的虚拟DOM中。有任何想法吗?
一种策略可能是构建一个黑匣子组件,您永远不要让React更新。组件生命周期方法shouldComponentUpdate()旨在允许组件自行确定是否需要重新渲染。如果您 始终false从该方法返回,React将永远不会深入到子元素中(也就是说,除非您调用forceUpdate()),所以这将成为抵御React深度更新系统的一种防火墙。
shouldComponentUpdate()
false
forceUpdate()
使用第一个调用render()生成图表的容器,然后在componentDidMount()方法中使用D3绘制图表本身。然后就归结为响应React组件的更新来更新您的图表。尽管您可能不 应该 在中执行类似的操作shouldComponentUpdate(),但我看不出没有真正的理由不能继续从那里调用D3更新(请参阅React组件的代码_performUpdateIfNecessary())。
render()
componentDidMount()
_performUpdateIfNecessary()
因此您的组件将如下所示:
React.createClass({ render: function() { return <svg></svg>; }, componentDidMount: function() { d3.select(this.getDOMNode()) .call(chart(this.props)); }, shouldComponentUpdate: function(props) { d3.select(this.getDOMNode()) .call(chart(props)); return false; } });
请注意,您需要在componentDidMount()方法(用于第一个渲染)和方法shouldComponentUpdate()(用于后续更新)中调用图表。还要注意,您需要一种将组件属性或状态传递到图表的方法,并且它们是特定于上下文的:在第一个渲染中,已经在this.props和上设置了它们this.state,但是在以后的更新中,尚未设置新的属性。在组件上,因此您需要使用功能参数。
this.props
this.state
在这里查看jsfiddle 。