ReactJS componentDidMount + 渲染
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 (
<div className="row pushdown">
<div className="d3-block">
<div className="Chart" />
</div>
</div>
);
}
}
在第 3 行,el
被赋值 this.getDOMNode();
,它始终指向渲染函数中的顶级元素 (div "row pushdown"
)。那么 this.getDOMNode()
是否总是引用渲染函数中的顶级元素?我实际上想做的是在最里面的 div
(.Chart
) 内渲染 d3 图表。我首先尝试做 this.getDOMNode().find('.Chart')
但那没有用。
第一个问题:我知道我不应该在这里尝试触摸真实的 DOM,但是我如何才能在虚拟DOM 上进一步选择一些东西?
第二个问题:我知道,鉴于我对此很陌生,我可能做错了。你能在这里推荐一个更好的方法吗?
第三个问题:我想在 ".Chart"
的兄弟 div
中添加图表图例。我应该为此创建一个新组件吗?或者在我的 d3Chart 中我可以使用选择器来做到这一点吗?
提前感谢您的帮助!
P.S。我有一个问题:
我看到人们在其中使用 React.render(<Chart />,document.body)
而不是 React.createElement
。有人能给我解释一下区别吗?
是的,getDOMNode()
returns 最外面的 DOM 元素 render
ed。
A1。我建议您使用 ref
属性 (documentation),它提供对 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。虽然最终您可能希望将代码重构为多个组件,但您创建的内容没有任何问题(假设您尝试了上面提到的 ref
选项)。
A3。由于图例代表了一个非常不同的功能(并且是孤立的),因此创建一个独特的组件将是典型的 React。您可能仍然有一个 Chart
组件,它既包含实际图表可视化,也包含另一个显示图例的组件。这是一个很好的关注点分离。但是,您也可以考虑一个 Flux 模型,其中每个组件都监听变化并完全独立地呈现其视觉效果。如果它们紧密合作,Flux 模型可能就没有那么大的意义了。
侧面:使用 JSX,您可能会看到:
React.render(<App />, document.body)
这只会将 App
渲染到文档正文内容中。
相当于预编译的 JSX:
React.render(React.createElement(App, null), document.body);
请注意...从 v0.13 开始。 componentDidMount()
可能还没有 this.refs
可用。来自更新日志:
ref
解析顺序略有改变,组件的 ref 在 componentDidMount
方法被调用后立即可用;仅当您的组件在 componentDidMount
中调用父组件的回调时,才应观察到此更改,这是一种反模式,无论如何都应避免
渲染从 parent 变为 childrem。所以 componentDidMount
可能没有 refs
到 child 节点,而是放置 setTimeout
函数,所以所有 child 节点都被渲染并且 refs 将可用于操作
请注意,从 React v15.0 开始,getDOMNode()
已被删除(自 v0.13 起已弃用)并且不能再使用。
编辑:在以下答案中对 getDOMNode()
的弃用和 React.findDOMNode(component)
的引入(您应该改用)进行了详尽的解释:
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 (
<div className="row pushdown">
<div className="d3-block">
<div ref="chartComp" className="Chart" />
</div>
</div>
);
}
});
我目前正在使用 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>
);
}
}
在第 3 行,el
被赋值 this.getDOMNode();
,它始终指向渲染函数中的顶级元素 (div "row pushdown"
)。那么 this.getDOMNode()
是否总是引用渲染函数中的顶级元素?我实际上想做的是在最里面的 div
(.Chart
) 内渲染 d3 图表。我首先尝试做 this.getDOMNode().find('.Chart')
但那没有用。
第一个问题:我知道我不应该在这里尝试触摸真实的 DOM,但是我如何才能在虚拟DOM 上进一步选择一些东西?
第二个问题:我知道,鉴于我对此很陌生,我可能做错了。你能在这里推荐一个更好的方法吗?
第三个问题:我想在 ".Chart"
的兄弟 div
中添加图表图例。我应该为此创建一个新组件吗?或者在我的 d3Chart 中我可以使用选择器来做到这一点吗?
提前感谢您的帮助!
P.S。我有一个问题:
我看到人们在其中使用 React.render(<Chart />,document.body)
而不是 React.createElement
。有人能给我解释一下区别吗?
是的,getDOMNode()
returns 最外面的 DOM 元素 render
ed。
A1。我建议您使用 ref
属性 (documentation),它提供对 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。虽然最终您可能希望将代码重构为多个组件,但您创建的内容没有任何问题(假设您尝试了上面提到的 ref
选项)。
A3。由于图例代表了一个非常不同的功能(并且是孤立的),因此创建一个独特的组件将是典型的 React。您可能仍然有一个 Chart
组件,它既包含实际图表可视化,也包含另一个显示图例的组件。这是一个很好的关注点分离。但是,您也可以考虑一个 Flux 模型,其中每个组件都监听变化并完全独立地呈现其视觉效果。如果它们紧密合作,Flux 模型可能就没有那么大的意义了。
侧面:使用 JSX,您可能会看到:
React.render(<App />, document.body)
这只会将 App
渲染到文档正文内容中。
相当于预编译的 JSX:
React.render(React.createElement(App, null), document.body);
请注意...从 v0.13 开始。 componentDidMount()
可能还没有 this.refs
可用。来自更新日志:
ref
解析顺序略有改变,组件的 ref 在 componentDidMount
方法被调用后立即可用;仅当您的组件在 componentDidMount
中调用父组件的回调时,才应观察到此更改,这是一种反模式,无论如何都应避免
渲染从 parent 变为 childrem。所以 componentDidMount
可能没有 refs
到 child 节点,而是放置 setTimeout
函数,所以所有 child 节点都被渲染并且 refs 将可用于操作
请注意,从 React v15.0 开始,getDOMNode()
已被删除(自 v0.13 起已弃用)并且不能再使用。
编辑:在以下答案中对 getDOMNode()
的弃用和 React.findDOMNode(component)
的引入(您应该改用)进行了详尽的解释:
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 (
<div className="row pushdown">
<div className="d3-block">
<div ref="chartComp" className="Chart" />
</div>
</div>
);
}
});