Reputation: 664
I've been looking at the documentation here https://reactjs.org/docs/react-component.html, but there is something that keeps bugging me. A pattern which I almost constantly seem to need but I am unable to find a solution to it and so always have to find hacks around it.
The pattern that I'm talking about is as follows. My app has a TabNavigator and I understand that when the app gets initialised ComponentDidMount is called on all the tabs. What I would like are functions that get called when a Tab is either navigated to, using this.props.navigation.navigate('TAB1')
or when the tab is clicked at the bottom of the screen.
If someone can help with this I'd really appreciate it. Apologies there is no code to show for this.
Thanks
Upvotes: 0
Views: 910
Reputation: 408
First, to understand the reason why it's not so easy, read the following conversation in the corresponding issue: https://github.com/react-navigation/react-navigation/issues/51
Here is what currently looks like the most effective solution: https://github.com/react-navigation/react-navigation/pull/3345
And this is the example code you can try out:
import type {
NavigationScreenProp,
NavigationEventSubscription,
} from 'react-navigation';
import React from 'react';
import { Button, Platform, ScrollView, StatusBar, View } from 'react-native';
import { SafeAreaView, TabNavigator } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
import SampleText from './SampleText';
const MyNavScreen = ({ navigation, banner }) => (
<SafeAreaView forceInset={{ horizontal: 'always', top: 'always' }}>
<SampleText>{banner}</SampleText>
<Button
onPress={() => navigation.navigate('Home')}
title="Go to home tab"
/>
<Button
onPress={() => navigation.navigate('Settings')}
title="Go to settings tab"
/>
<Button onPress={() => navigation.goBack(null)} title="Go back" />
<StatusBar barStyle="default" />
</SafeAreaView>
);
const MyHomeScreen = ({ navigation }) => (
<MyNavScreen banner="Home Tab" navigation={navigation} />
);
MyHomeScreen.navigationOptions = {
tabBarTestIDProps: {
testID: 'TEST_ID_HOME',
accessibilityLabel: 'TEST_ID_HOME_ACLBL',
},
tabBarLabel: 'Home',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-home' : 'ios-home-outline'}
size={26}
style={{ color: tintColor }}
/>
),
};
type MyPeopleScreenProps = {
navigation: NavigationScreenProp<*>,
};
class MyPeopleScreen extends React.Component<MyPeopleScreenProps> {
_s0: NavigationEventSubscription;
_s1: NavigationEventSubscription;
_s2: NavigationEventSubscription;
_s3: NavigationEventSubscription;
static navigationOptions = {
tabBarLabel: 'People',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-people' : 'ios-people-outline'}
size={26}
style={{ color: tintColor }}
/>
),
};
componentDidMount() {
this._s0 = this.props.navigation.addListener('willFocus', this._onEvent);
this._s1 = this.props.navigation.addListener('didFocus', this._onEvent);
this._s2 = this.props.navigation.addListener('willBlur', this._onEvent);
this._s3 = this.props.navigation.addListener('didBlur', this._onEvent);
}
componentWillUnmount() {
this._s0.remove();
this._s1.remove();
this._s2.remove();
this._s3.remove();
}
_onEvent = a => {
console.log('EVENT ON PEOPLE TAB', a.type, a);
};
render() {
const { navigation } = this.props;
return <MyNavScreen banner="People Tab" navigation={navigation} />;
}
}
type MyChatScreenProps = {
navigation: NavigationScreenProp<*>,
};
class MyChatScreen extends React.Component<MyChatScreenProps> {
_s0: NavigationEventSubscription;
_s1: NavigationEventSubscription;
_s2: NavigationEventSubscription;
_s3: NavigationEventSubscription;
static navigationOptions = {
tabBarLabel: 'Chat',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-chatboxes' : 'ios-chatboxes-outline'}
size={26}
style={{ color: tintColor }}
/>
),
};
componentDidMount() {
this._s0 = this.props.navigation.addListener('willFocus', this._onEvent);
this._s1 = this.props.navigation.addListener('didFocus', this._onEvent);
this._s2 = this.props.navigation.addListener('willBlur', this._onEvent);
this._s3 = this.props.navigation.addListener('didBlur', this._onEvent);
}
componentWillUnmount() {
this._s0.remove();
this._s1.remove();
this._s2.remove();
this._s3.remove();
}
_onEvent = a => {
console.log('EVENT ON CHAT TAB', a.type, a);
};
render() {
const { navigation } = this.props;
return <MyNavScreen banner="Chat Tab" navigation={navigation} />;
}
}
const MySettingsScreen = ({ navigation }) => (
<MyNavScreen banner="Settings Tab" navigation={navigation} />
);
MySettingsScreen.navigationOptions = {
tabBarLabel: 'Settings',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-settings' : 'ios-settings-outline'}
size={26}
style={{ color: tintColor }}
/>
),
};
const SimpleTabs = TabNavigator(
{
Home: {
screen: MyHomeScreen,
path: '',
},
People: {
screen: MyPeopleScreen,
path: 'cart',
},
Chat: {
screen: MyChatScreen,
path: 'chat',
},
Settings: {
screen: MySettingsScreen,
path: 'settings',
},
},
{
lazy: true,
removeClippedSubviews: true,
tabBarOptions: {
activeTintColor: Platform.OS === 'ios' ? '#e91e63' : '#fff',
},
}
);
type SimpleTabsContainerProps = {
navigation: NavigationScreenProp<*>,
};
class SimpleTabsContainer extends React.Component<SimpleTabsContainerProps> {
static router = SimpleTabs.router;
_s0: NavigationEventSubscription;
_s1: NavigationEventSubscription;
_s2: NavigationEventSubscription;
_s3: NavigationEventSubscription;
componentDidMount() {
this._s0 = this.props.navigation.addListener('willFocus', this._onAction);
this._s1 = this.props.navigation.addListener('didFocus', this._onAction);
this._s2 = this.props.navigation.addListener('willBlur', this._onAction);
this._s3 = this.props.navigation.addListener('didBlur', this._onAction);
}
componentWillUnmount() {
this._s0.remove();
this._s1.remove();
this._s2.remove();
this._s3.remove();
}
_onAction = a => {
console.log('TABS EVENT', a.type, a);
};
render() {
return <SimpleTabs navigation={this.props.navigation} />;
}
}
export default SimpleTabsContainer;
For the source and other codes, look here: https://github.com/react-navigation/react-navigation/blob/master/examples/NavigationPlayground/js/SimpleTabs.js
Upvotes: 1