You should probably see the react components as a tree and you can pass the function that you want to trigger from parents to children as props.
Say you have a Tab component -
const Tab = React.createClass({
onPressButton(){
triggeredFunction();
},
render() {
return (
<Button onPress={this.onPressButton}>
<Text>Press Me!</Text>
</Button>
);
},
});
You can simply call triggeredFunction()
(or this.onPressButton
from within the component) if you want to emulate the touch.
If you are trying to trigger the function from a parent component, you should probably have the triggered function in the parent and pass it as prop -
const Tab = React.createClass({
propTypes: {
onPressButton: React.PropTypes.func,
tabNumber: React.PropTypes.number,
tabText: React.PropTypes.string,
},
triggerTheTriggerToTrigger() {
// This will trigger the triggeredFunction in the page component and pass in the tab number
// Remember that onPressButton={this.triggeredFunction}
// So you are calling this.triggeredFunction(tabNumber) in the parent page component
this.props.onPressButton(this.props.tabNumber);
},
render() {
return (
<Button onPress={this.triggerTheTriggerToTrigger}>
<Text>{this.props.tabText}</Text>
</Button>
);
},
});
Then in your main component
const Page = React.createClass({
getInitialState() {
return {
currentTab: 1,
};
},
triggeredFunction(tabNum) {
// This function is setting the state of the page component to be equal to that passed from the tab
// So when the tab is touched it will trigger the page to change to that number.
this.setState({
currentTab: tabNum,
});
},
// main component render:
render() {
let content;
// We are setting the page 'content' from here
// Choosing the content from the currentTab state
switch (this.state.currentTab) {
case 1:
content = <Text>This is the content for tab 1</Text>
break
case 2:
content = <Text>Tab 2 has a slightly different message</Text>
break
case 3:
content = <Text>Tab 3 is slightly different too</Text>
break
}
return (
<View className="page">
<View className="toptabs">
<Tab onPressButton={this.triggeredFunction} tabText="Button 1" tabNumber={1} />
<Tab onPressButton={this.triggeredFunction} tabText="Button 2" tabNumber={2} />
<Tab onPressButton={this.triggeredFunction} tabText="Button 3" tabNumber={3} />
</View>
<View className="pageContent">
{content}
</View>
</View>
);
},
});
Then you can call this.triggeredFunction()
from the main component instead. I hope this makes sense.
I haven't tested this code, so it might need some tweaking, but hopefully it shows you the logic behind it.
Also, I'm using a switch statement here to make what is going on obvious. I wouldn't probably use this method in a real app (not that it's particularly awful). You could also load in other components and conditionally load them based on the currentTab state. You could create an array of contents and have -
let content = contents[this.state.currentTab];
You can also achieve this through other means. I'm using flux in my app, which consists of store that you update. These stores then propagate the view with data. This means you get more of a global setting. If you were using flux then you would basically set the page state (i.e. tabNumber) from flux.
So, in your tab you could set onPressButton to -
this.flux.action.updateTab(this.props.tabNumber);
This would update the global store to set what tabNumber you are on (i.e. you are not just setting currentTab on the page component anymore)
And in your page you could get your currentTab state from something like -
currentTab: this.flux.store.tabStore.getCurrentTab()
So the store updates your page component when it updates.
But this is a more complicated implementation than you are using and it's beyond the scope of what we are discussing here. Don't worry if that part is confusing, but it may be helpful to consider it if you are building something larger in the future (imagine 10 different app 'pages' with tab sections for different things, suddenly you want a storage place where you can control the state of them, rather than in each set of components).