Jarryd Goodman Jarryd Goodman - 9 months ago 51
Javascript Question

ReactJS componentDidMount + render

I am currently using react to create d3 visualizations. I'm a little confused about the relationship between the

methods (is methods the proper term?). Here is what I have (I excluded some code for simplicity):

var Chart = React.createClass({
componentDidMount: function () {
var el = this.getDOMNode();
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" />

On line 3,
gets assigned
which always points to the top level element in the render function (
div "row pushdown"
). So does
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
). I first tried doing
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
. Should I be creating a new component 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
within that. Could somebody explain to me the difference?


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" />

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. While ultimately you might want to refactor your code into multiple components, 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 component would be typical React. You might still have a Chart component that contains both the actual chart visualization but also has another component which displays a legend. It's a nice separation of concerns. But, you could also consider a Flux model where each component listens for changes and renders its visuals completely 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 precompiled JSX:

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