I'm building an electronic resistance calculator with ReactJS. I have a composed component declared as so:
var ResistanceCalculator = React.createClass({
getInitialState: function() {
return {bands: [0,0,0,0,0]}
},
componentDidMount: 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?
The 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
component, 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 components who want to transparently render their content while doing some work themselves.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With