I'm building an electronic resistance calculator with ReactJS. I have a posed ponent declared as so:
var ResistanceCalculator = React.createClass({
getInitialState: function() {
return {bands: [0,0,0,0,0]}
},
ponentDidMount: function() {
console.log(this.props.children); // => undefined
},
render: function() {
return (
<div>
<OhmageIndicator bands={this.state.bands} />
<SVGResistor bands={this.state.bands} />
<BandSelector band={1} />
<BandSelector band={2} />
<BandSelector band={3} />
<BandSelector band={4} />
<BandSelector band={5} />
</div>
);
}
});
BandSelector renders <select>
elements and when one changes I want to update ResistanceCalculator
's state. So my thinking was that I need to bind an event listener to ResistanceCalculator
children. However this.props.children
seems to be empty. Why is this?
I'm building an electronic resistance calculator with ReactJS. I have a posed ponent declared as so:
var ResistanceCalculator = React.createClass({
getInitialState: function() {
return {bands: [0,0,0,0,0]}
},
ponentDidMount: function() {
console.log(this.props.children); // => undefined
},
render: function() {
return (
<div>
<OhmageIndicator bands={this.state.bands} />
<SVGResistor bands={this.state.bands} />
<BandSelector band={1} />
<BandSelector band={2} />
<BandSelector band={3} />
<BandSelector band={4} />
<BandSelector band={5} />
</div>
);
}
});
BandSelector renders <select>
elements and when one changes I want to update ResistanceCalculator
's state. So my thinking was that I need to bind an event listener to ResistanceCalculator
children. However this.props.children
seems to be empty. Why is this?
1 Answer
Reset to default 13The rule of thumb is: everything that's in this.props
is passed down to you from the parent.
So you're using this.props.children
the wrong way. If I had something like this:
<Todos><div /><div /></Todos>
then, for the Todos
ponent, this.props.children
would be the array of divs
.
What you want here are simple callbacks (working example):
/** @jsx React.DOM */
var ResistanceCalculator = React.createClass({
getInitialState: function() {
return {bands: [0,0,0,0,0]};
},
handleBandSelectionChange: function(bandIndex, newValue) {
// for the sake of immutability, clone the array here
var bands = this.state.bands.slice(0);
bands[bandIndex] = newValue;
console.log(bandIndex, newValue); // yep, seems to work
this.setState({bands: bands});
},
render: function() {
return (
<div>
<OhmageIndicator bands={this.state.bands} />
{
this.state.bands.map(function(value, i) {
return (
<BandSelector band={i} onChange={this.handleBandSelectionChange}/>
);
}, this)
}
</div>
);
}
});
var BandSelector = React.createClass({
handleChange: function(e) {
if (this.props.onChange)
this.props.onChange(this.props.band, e.target.value);
},
render: function() {
return (
<select onChange={this.handleChange}>
<option value="1">1</option>
<option value="2">2</option>
</select>
);
}
});
I listen to the regular onChange
event from select, then in the handler I call my parent's handler (handleBandSelectionChange
). Note that, for the parent (ResistanceCalculator
), the event doesn't have to be onChange
; it could be any name, as long as the child calls it. It's just nicer to name it onChange
.
As a side note, this.props.children
is used for wrapper ponents who want to transparently render their content while doing some work themselves.