The React docs cover this in detail in "Communicate Between Components" and "Multiple Components". The gist is that the parent should pass a function as a prop to the child, and the child should call that function as a callback when it needs to:
var TabsExample = React.createClass({
handleTabClick: function(item) {
// Do something with item, maybe set it as active.
},
render: function() {
var tabs = [
{title: 'first', content: 'Content 1'},
{title: 'second', content: 'Content 2'}
];
return <div>
<TabsSwitcher items={tabs} onTabClick={this.handleTabClick}/>
<TabsContent items={tabs}/>
</div>;
}
});
var TabsSwitcher = React.createClass({
render: function() {
var items = this.props.items.map(function(item) {
return <a onClick={this.onClick.bind(this, item)}>{item.title}</a>;
}.bind(this));
return <div>{items}</div>;
},
onClick: function(item) {
this.props.onTabClick(item);
}
});
For the TabsContent
component, you should move the tabs
into the TabsExample
state so React can automatically re-render for you when they change. Since TabsSwitcher
and TabsContent
are passed the tabs in the render method, React knows they are dependent on the tabs and will re-render when the state changes:
var TabsExample = React.createClass({
getInitialState: function() {
return {
activeTabId: 1,
tabs: [
{title: 'first', content: 'Content 1', id: 1},
{title: 'second', content: 'Content 2', id: 2}
]
};
};
handleTabClick: function(item) {
// Call `setState` so React knows about the updated tab item.
this.setState({activeTabId: item.id});
},
render: function() {
return (
<div>
<TabsSwitcher items={this.state.tabs}
activeItemId={this.state.activeTabId}
onTabClick={this.handleTabClick}/>
<TabsContent items={this.state.tabs}
activeItemId={this.state.activeTabId}/>
</div>
);
}
});