ReactJS componentDidMount + 渲染

IT技术 javascript jquery d3.js reactjs
2021-04-29 01:15:38

我目前正在使用 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 行,elgetsassignedthis.getDOMNode();始终指向渲染函数 ( div "row pushdown") 中的顶级元素那么this.getDOMNode()总是引用渲染函数中的顶级元素吗?我真正想做的是在最里面的div( .Chart) 中渲染 d3 图表我第一次尝试这样做,this.getDOMNode().find('.Chart')但没有奏效。

第一个问题:我知道我不应该在这里尝试接触真正的 DOM,但是我将如何在 VirtualDOM 上进一步选择一些东西?

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

第三个问题:我想在同级添加图表图例div".Chart"我应该为此创建一个新组件吗?或者在我的 d3Chart 中我可以使用选择器来做到这一点吗?

预先感谢您的帮助!

PS我有一个问题:

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

4个回答

是的,getDOMNode()返回被render编辑的最外面的 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解析顺序略有变化,以便在componentDidMount调用方法后立即可以使用对组件的引用这种变化应该是可见的,仅仅如果组件调用你的内父组件的回调componentDidMount,这是一种反模式,应该不分避免

this.refs非常适合使用ReactDOM在react组件生命周期中找到任何 dom 节点react-dom使用 NPM安装或在您的页面中包含 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)(您应该使用)的详尽解释https : //stackoverflow.com/a/30191683/6223301