繁体   English   中英

ReactJS componentDidMount + render

[英]ReactJS componentDidMount + render

我目前正在使用react来创建d3可视化。 我对rendercomponenetDidMount方法之间的关系有点困惑(方法是正确的术语吗?)。 这就是我所拥有的(为简单起见,我排除了一些代码):

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,但是如何在VirtualDOM上选择更多内容呢?

第二个问题:我知道,鉴于我对此很陌生,我可能做错了。 你能在这里建议一个更好的方法吗?

第三个问题:我想在".Chart"的兄弟div中添加一个图表图例。 我应该为此创建一个新组件吗? 或者在我的d3Chart中我可以使用选择器来执行此操作吗?

预先感谢您的帮助!

PS我有一个问题:

我见过人们使用React.render(<Chart />,document.body)而不是在其中使用React.createElement 有人可以向我解释一下这个区别吗?

是的, getDOMNode()返回render ed的最外层DOM元素。

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。 虽然最终您可能希望将代码重构为多个组件,但您创建的内容没有任何问题(假设您尝试上面提到的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 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 (
        <div className="row pushdown">
                <div className="d3-block">
                    <div ref="chartComp" className="Chart" />
                </div>
        </div>
    );
  }
});

请注意,从React v15.0开始, getDOMNode()被删除(自v0.13起不推荐使用),因此无法再使用。

编辑:在以下答案中有关于弃用getDOMNode()和引入React.findDOMNode(component) (您应该使用它)的详细说明: httpsReact.findDOMNode(component)

渲染从父母到childrem。 所以componentDidMount可能没有refs到子节点而是放入setTimeout函数,所以所有子节点都被渲染,refs可用于动作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM