ReactJS componentDidMount + render
我目前正在使用react来创建d3可视化。 我对render
和componenetDidMount
方法之间的关系有点困惑(方法是正确的术语吗?)。 这就是我所拥有的(为简单起见,我排除了一些代码):
var Chart = React.createClass({ componentDidMount: function () { var el = this.getDOMNode(); console.log(el); d3Chart.create(el, { width: '500', height: '300' }, this.getChartState(),this.getAccessState); }, render: function () { return ( ); } }
在第3行, el
被赋予this.getDOMNode();
它始终指向渲染函数中的顶级元素( div "row pushdown"
)。 那么this.getDOMNode()
总是引用渲染函数中的顶级元素吗? 我实际上要做的是在最里面的div
( .Chart
)中渲染d3图表。 我首先尝试这样做this.getDOMNode().find('.Chart')
但是没有用。
第一个问题:我知道我不应该尝试触摸真正的DOM,但是如何在VirtualDOM上选择更多内容呢?
第二个问题:我知道,鉴于我对此很陌生,我可能做错了。 你能建议一个更好的方法吗?
第三个问题:我想在".Chart"
的兄弟div
中添加一个图表图例。 我应该为此创建一个新组件吗? 或者在我的d3Chart中,我可以使用选择器来执行此操作吗?
预先感谢您的帮助!
PS我有一个问题:
我见过人们使用React.render(,document.body)
而不是在其中使用React.createElement
。 有人可以向我解释一下这个区别吗?
是的, getDOMNode()
返回render
ed的最外层DOM元素。
A1。 我建议你使用ref
属性( 文档 ),它提供对DOM元素的引用以供以后使用:
componentDidMount: function() { // << you can get access to the element by name as shown below var chart = this.refs.chart; // do what you want here ... }
A2。 虽然最终您可能希望将代码重构为多个组件,但您创建的内容没有任何问题(假设您尝试了上面提到的ref
选项)。
A3。 由于图例代表了一个非常不同的function(并且是孤立的),因此创建一个独特的组件将是典型的React。 您可能仍然有一个Chart
组件,其中既包含实际图表可视化,也包含另一个显示图例的组件。 这是一个很好的分离关注点。 但是,您还可以考虑使用Flux模型,其中每个组件都会侦听更改并完全独立地呈现其视觉效果。 如果它们紧密配合在一起,Flux模型可能没有多大意义。
方:使用JSX,您可能会看到:
React.render( , document.body)
这只会将App
呈现为文档正文内容。
这相当于预编译的JSX:
React.render(React.createElement(App, null), document.body);
只是一个注释……从v0.13开始。 componentDidMount()
可能还没有this.refs
可用。 来自更改日志:
ref
resolution命令稍有改动,以便在调用componentDidMount
方法后立即获得组件的引用; 只有当组件在componentDidMount中调用父组件的回调时,才应观察到此更改,这是一种反模式,应该避免
this.refs
非常适合使用ReactDOM
库在反应组件生命周期中查找任何dom节点。 使用NPM安装react-dom
或在页面中包含JS。
因此,您的整个组件代码应如下所示:
import React from 'react'; import ReactDOM from 'react-dom'; var Chart = React.createClass({ componentDidMount: function () { var el = ReactDOM.findDOMNode(this.refs.chartComp); console.log(el); d3Chart.create(el, { width: '500', height: '300' }, this.getChartState(),this.getAccessState); }, render: function () { return ( ); } }
请注意,从React v15.0开始, getDOMNode()
被删除(自v0.13起不推荐使用),并且无法再使用。
编辑:在以下答案中有关于弃用getDOMNode()
和引入React.findDOMNode(component)
(您应该使用它)的详细解释: https : React.findDOMNode(component)
渲染从父母到childrem。 所以componentDidMount
可能没有refs
子节点而是放入setTimeout
函数,因此所有子节点都被渲染,refs可用于动作