I'm working with a RadioButtonGroup component which is like radio input but with buttons:
It would be good if using the component was easy like this:
var SelectThing = React.createClass({
render: function render() {
// I would not like to add onClick handler to every button element
// outside the RadioButtonGroup component
return (
<RadioButtonGroup onChange={this._onActiveChange}>
<button>Thing 1</button>
<button>Thing 2</button>
<button>Thing 3</button>
</RadioButtonGroup>
)
},
_onActiveChange: function _onActiveChange(index) {
console.log('You clicked button with index:', index);
}
});
The actual question: How can I achieve that the most elegantly with React? (I found another similar question but it doesn't exactly answer to this).
My first intuition was to add and remove the onClick handlers inside the component to remove boiler plate code from the component's user. Another option that comes to my mind is to give e.g. <p>
elements instead of button elements and put them inside button elements which would be created inside the RadioButtonGroup component. I don't like the latter that much because it doesn't make that much sense semantically compared to passing buttons.
Here's what the (obviously not working) component looks like now:
// Radio input with buttons
// http://getbootstrap.com/javascript/#buttons-checkbox-radio
var RadioButtonGroup = React.createClass({
getInitialState: function getInitialState() {
return {
active: this.props.active || 0
};
},
componentWillMount: function componentWillMount() {
var buttons = this.props.children;
buttons[this.props.active].className += ' active';
var self = this;
buttons.forEach(function(button, index) {
// How to dynamically set onclick handler for virtual dom
// element created inside JSX?
button.addEventListener('onClick', function(event) {
self._onAnyButtonClick(index, event);
}
});
},
componentWillUnmount: function componentWillUnmount() {
var buttons = this.props.children;
buttons.forEach(function(button, index) {
button.removeEventListener('onClick');
});
},
render: function render() {
return (
<div className="radio-button-group">
{buttons}
</div>
)
},
_onAnyButtonClick: function _onAnyButtonClick(index, event) {
this.setState({
active: index
});
this.props.onChange(index);
}
});