【问题标题】:ReactJS componentDidMount + renderReactJS 组件DidMount + 渲染
【发布时间】:2023-04-10 05:08:01
【问题描述】:

我目前正在使用 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 中我可以使用选择器来执行此操作吗?

提前感谢您的帮助!

附:我有一个问题:

我看到人们在其中使用React.render(&lt;Chart /&gt;,document.body) 而不是React.createElement。有人可以向我解释其中的区别吗?

【问题讨论】:

    标签: javascript jquery d3.js reactjs


    【解决方案1】:

    是的,getDOMNode() 返回最外层的 DOM 元素,即 rendered。

    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);
    

    【讨论】:

    • 非常感谢!我必须 cmets/问题: A3:我的图例和图表将绑定到相同的数据,所以如果我要使用新数据更新状态,则两者都需要更新。我将研究什么是 Flux 模型,但它们确实紧密结合在一起。 Side:所以唯一的区别是它是否是预编译的?后者是预编译版本。
    • 侧面:是的,这是唯一的区别。
    【解决方案2】:

    请注意...从 v0.13 开始。 componentDidMount() 可能还没有 this.refs 可用。来自更新日志:

    ref 解析顺序略有变化,因此在调用 componentDidMount 方法后,组件的引用立即可用;仅当您的组件在 componentDidMount 中调用父组件的回调时,此更改才应该是可观察到的,这是一种反模式,无论如何都应该避免

    【讨论】:

      【解决方案3】:

      this.refs 非常适合使用ReactDOM 库在 React 组件生命周期中查找任何 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>
          );
        }
      });
      

      【讨论】:

        【解决方案4】:

        请注意,从 React v15.0 开始,getDOMNode() 已被删除(自 v0.13 起已弃用)并且不能再使用。

        编辑:在以下答案中有关于弃用getDOMNode() 和引入React.findDOMNode(component)(您应该使用它)的详尽解释: https://stackoverflow.com/a/30191683/6223301

        【讨论】:

        • 能否请您对您提供的解释添加更多描述?
        • 添加了链接描述。昨天偶然发现了这个问题,实际上想评论接受的答案,但我还不能这样做(缺少代表)。因此,此评论与原始问题不是 100% 相关,如果认为不有益,可以删除评论。
        【解决方案5】:

        渲染从父级到子级。所以componentDidMount 可能没有refs 到子节点,而是把setTimeout 函数,所以所有子节点都被渲染并且引用将可用于操作

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-07-20
          • 1970-01-01
          • 2023-04-11
          • 2017-03-16
          • 2020-06-20
          • 2020-03-23
          • 2015-01-27
          • 1970-01-01
          相关资源
          最近更新 更多