最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ReactJS componentDidMount + render - Stack Overflow

programmeradmin5浏览0评论

I am currently using react to create d3 visualizations. I'm a little confused about the relationship between the render and ponenetDidMount methods (is methods the proper term?). Here is what I have (I excluded some code for simplicity):

var Chart = React.createClass({
  ponentDidMount: 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.

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?

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 ponent for this? Or in my d3Chart can I use selectors to do this?

Thank you in advance for your help!

P.S. I have one side question:

I've seen people use React.render(<Chart />,document.body) instead of using React.createElement within that. Could somebody explain to me the difference?

I am currently using react to create d3 visualizations. I'm a little confused about the relationship between the render and ponenetDidMount methods (is methods the proper term?). Here is what I have (I excluded some code for simplicity):

var Chart = React.createClass({
  ponentDidMount: 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.

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?

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 ponent for this? Or in my d3Chart can I use selectors to do this?

Thank you in advance for your help!

P.S. I have one side question:

I've seen people use React.render(<Chart />,document.body) instead of using React.createElement within that. Could somebody explain to me the difference?

Share Improve this question edited Feb 22, 2015 at 20:46 WiredPrairie 59.8k18 gold badges117 silver badges145 bronze badges asked Feb 22, 2015 at 20:06 Jarryd GoodmanJarryd Goodman 4873 gold badges9 silver badges19 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 8

Yes, getDOMNode() returns the outermost DOM element that was rendered.

A1. I'd suggest you use a ref attribute (documentation) which provides a reference to the DOM element for later usage:

<div ref="chart" className="Chart" />

ponentDidMount: 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 ponents, there's nothing wrong with what you've created (assuming you try the ref option mentioned above).

A3. As the legend would represent a very different piece of functionality (and isolated), creating a distinct ponent would be typical React. You might still have a Chart ponent that contains both the actual chart visualization but also has another ponent which displays a legend. It's a nice separation of concerns. But, you could also consider a Flux model where each ponent listens for changes and renders its visuals pletely independently. If they work tightly together, a Flux model may not make as much sense.

Side: Using JSX, you might see:

React.render(<App />, document.body)

That would just render the App into the document body contents.

That is equivalent to prepiled JSX:

React.render(React.createElement(App, null), document.body);

Just a note...as of v0.13. ponentDidMount() may not yet have this.refs available. From the changelog:

ref resolution order has changed slightly such that a ref to a ponent is available immediately after its ponentDidMount method is called; this change should be observable only if your ponent calls a parent ponent's callback within your ponentDidMount, which is an anti-pattern and should be avoided regardless

this.refs is perfect to find any dom node in react ponent life cycle using ReactDOM library. Install react-dom with NPM or include the JS in your page.

So your entire ponent code should look like this:

import React from 'react';
import ReactDOM from 'react-dom';

var Chart = React.createClass({
  ponentDidMount: 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>
    );
  }
});

Please note that as of React v15.0 getDOMNode() is removed (deprecated since v0.13) and can no longer be used.

edit: There's a thorough explanation about deprecation of getDOMNode() and introduction of React.findDOMNode(ponent) (that you should use instead) in the following answer: https://stackoverflow./a/30191683/6223301

rendering go from parent to childrem. So ponentDidMount may not have refs to child nodes instead put setTimeout function so all child node got rendered and refs will be available for actions

发布评论

评论列表(0)

  1. 暂无评论