javascript ReactJS componentDidMount + 渲染
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28662624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ReactJS componentDidMount + render
提问by Jarryd Goodman
I am currently using react to create d3 visualizations. I'm a little confused about the relationship between the render
and componenetDidMount
methods (is methods the proper term?). Here is what I have (I excluded some code for simplicity):
我目前正在使用 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 (
<div className="row pushdown">
<div className="d3-block">
<div className="Chart" />
</div>
</div>
);
}
}
On line 3, el
gets assigned this.getDOMNode();
which always points to the top level element in the render function (div "row pushdown"
). So does this.getDOMNode()
always refer to the top level element in the render function? What I'm actually trying to do is render the d3 chart within the innermost div
(.Chart
). I first tried doing this.getDOMNode().find('.Chart')
but that didn't work.
在第 3 行,el
getsassignedthis.getDOMNode();
始终指向渲染函数 ( div "row pushdown"
) 中的顶级元素。那么this.getDOMNode()
总是引用渲染函数中的顶级元素吗?我真正想做的是在最里面的div
( .Chart
) 中渲染 d3 图表。我第一次尝试这样做,this.getDOMNode().find('.Chart')
但没有奏效。
First question: I know that I shouldn't be trying to touch the real DOM here but how would I go about selecting something further down on the VirtualDOM?
第一个问题:我知道我不应该在这里尝试接触真正的 DOM,但是我将如何在 VirtualDOM 上进一步选择一些东西?
Second question: I know that, given I am very new to this, am probably doing this the wrong way. Can you suggest a better method here?
第二个问题:我知道,鉴于我对此很陌生,可能是我做错了。你能在这里提出更好的方法吗?
Third question: I want to add a chart legend in a sibling div
of ".Chart"
. Should I be creating a new component for this? Or in my d3Chart can I use selectors to do this?
第三个问题:我想在同级添加图表图例div
的".Chart"
。我应该为此创建一个新组件吗?或者在我的 d3Chart 中我可以使用选择器来做到这一点吗?
Thank you in advance for your help!
预先感谢您的帮助!
P.S. I have one side question:
PS我有一个问题:
I've seen people use React.render(<Chart />,document.body)
instead of using React.createElement
within that. Could somebody explain to me the difference?
我见过人们使用React.render(<Chart />,document.body)
而不是在其中使用React.createElement
。有人可以向我解释其中的区别吗?
回答by WiredPrairie
Yes, getDOMNode()
returns the outermost DOM element that was render
ed.
是的,getDOMNode()
返回被render
编辑的最外面的 DOM 元素。
A1. I'd suggest you use a ref
attribute (documentation) which provides a reference to the DOM element for later usage:
A1. 我建议您使用一个ref
属性(文档),它提供对 DOM 元素的引用以供以后使用:
<div ref="chart" className="Chart" />
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. While ultimately you might want to refactor your code into multiple components, there's nothing wrong with what you've created (assuming you try the ref
option mentioned above).
A2。虽然最终您可能希望将代码重构为多个组件,但您创建的内容并没有错(假设您尝试了ref
上述选项)。
A3. As the legend would represent a very different piece of functionality (and isolated), creating a distinct component would be typical React. You might still have a Chart
component that contains both the actual chart visualization but also has another component which displays a legend. It's a nice separation of concerns. But, you could also consider a Flux model where each component listens for changes and renders its visuals completely independently. If they work tightly together, a Flux model may not make as much sense.
A3. 由于图例将代表一个非常不同的功能(并且是孤立的),因此创建一个独特的组件将是典型的 React。您可能仍然有一个Chart
组件,它既包含实际的图表可视化,又包含另一个显示图例的组件。这是一个很好的关注点分离。但是,您也可以考虑一个 Flux 模型,其中每个组件都可以完全独立地侦听更改并呈现其视觉效果。如果它们紧密配合,Flux 模型可能没有多大意义。
Side: Using JSX, you might see:
侧面:使用 JSX,你可能会看到:
React.render(<App />, document.body)
That would just render the App
into the document body contents.
那只会将 渲染App
到文档正文内容中。
That is equivalent to precompiled JSX:
这相当于预编译的 JSX:
React.render(React.createElement(App, null), document.body);
回答by GAEfan
Just a note...as of v0.13. componentDidMount()
may not yet have this.refs
available. From the changelog:
只是一个说明...从 v0.13 开始。 componentDidMount()
可能还没有this.refs
。从变更日志:
ref
resolution order has changed slightly such that a ref to a component is available immediately after its componentDidMount
method is called; this change should be observable only if your component calls a parent component's callback within your componentDidMount
, which is an anti-pattern and should be avoided regardless
ref
解析顺序略有变化,以便在componentDidMount
调用其方法后立即可以使用对组件的引用;这种变化应该是可见的,仅仅如果组件调用你的内父组件的回调componentDidMount
,这是一种反模式,应该不分避免
回答by Manish Jangir
this.refs
is perfect to find any dom node in react component life cycle using ReactDOM
library. Install react-dom
with NPM or include the JS in your page.
this.refs
非常适合使用ReactDOM
库在反应组件生命周期中找到任何 dom 节点。react-dom
使用 NPM安装或在您的页面中包含 JS。
So your entire component code should look like this:
所以你的整个组件代码应该是这样的:
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 (
<div className="row pushdown">
<div className="d3-block">
<div ref="chartComp" className="Chart" />
</div>
</div>
);
}
});
回答by Anssi Moilanen
Please note that as of React v15.0 getDOMNode()
is removed (deprecated since v0.13) and can no longer be used.
请注意,自 React v15.0 起getDOMNode()
已删除(自 v0.13 起已弃用)并且不能再使用。
edit: There's a thorough explanation about deprecation of getDOMNode()
and introduction of React.findDOMNode(component)
(that you should use instead) in the following answer:
https://stackoverflow.com/a/30191683/6223301
编辑:在以下答案中有关于弃用getDOMNode()
和引入React.findDOMNode(component)
(您应该使用)的详尽解释:https:
//stackoverflow.com/a/30191683/6223301
回答by Tony Francis
rendering go from parent to childrem. So componentDidMount
may not have refs
to child nodes instead put setTimeout
function so all child node got rendered and refs will be available for actions
渲染从父级到子级。因此componentDidMount
可能不必使用refs
子节点代替 putsetTimeout
函数,以便所有子节点都被渲染并且 refs 可用于操作