The parent component should pass a callback to the children, and each child would trigger that callback when its state changes. You could actually hold all of the state in the parent, using it as a single point of truth, and pass the “selected” value down to each child as a prop.
In that case, the child could look like this:
var Child = React.createClass({
onToggle: function() {
this.props.onToggle(this.props.id, !this.props.selected);
},
render: function() {
return <button onClick={this.onToggle}>Toggle {this.props.label} - {this.props.selected ? 'Selected!' : ''}!</button>;
}
});
It has no state, it just fires an onToggle callback when clicked. The parent would look like this:
var Parent = React.createClass({
getInitialState: function() {
return {
selections: []
};
},
onChildToggle: function(id, selected) {
var selections = this.state.selections;
selections[id] = selected;
this.setState({
selections: selections
});
},
buildChildren: function(dataItem) {
return <Child
id={dataItem.id}
label={dataItem.label}
selected={this.state.selections[dataItem.id]}
onToggle={this.onChildToggle} />
},
render: function() {
return <div>{this.props.data.map(this.buildChildren)}</div>
}
});
It holds an array of selections in state and when it handles the callback from a child, it uses setState to re-render the children by passing its state down in the selected prop to each child.
You can see a working example of this here:
https://jsfiddle.net/fth25erj/