Note this was built for "react-navigation": "3.3.0" so your mileage my vary for more recent versions of Expo and react-navigation.
To make a modal appear when you tap on the last tab in a TabNavigator requires you to nest your TabNavigator inside a StackNavigator.
So we could set up something like this:
#App.js
A simple App.js.
import React from 'react';
import AppContainer from './MainNavigation';
export default class App extends React.Component {
constructor (props) {
super(props);
this.state = {
};
}
render () {
return (
<AppContainer />
);
}
}
#MainNavigation.js
This file contains two navigators. A TabNavigator and a StackNavigator. The TabNavigator is nested inside the StackNavigator.
To be able to show the ModalScreen we have to override the tabBarOnPress function inside the defaultNavigationOptions which is inside the config for the TabNavigator.
We need to check the navigation.state.key to see where we are navigating too. If we are going to Tab3 we can intercept the call and navigate to the ModalScreen instead. Otherwise we use the defaultHandler and go to the tab that was tapped.
import Screen1 from './Screen1';
import Screen2 from './Screen2';
import Screen3 from './Screen3';
import ModalScreen from './ModalScreen';
import { createBottomTabNavigator, createAppContainer, createStackNavigator } from 'react-navigation';
const screens = {
Tab1: {
screen: Screen1
},
Tab2: {
screen: Screen2
},
Tab3: {
screen: Screen3
}
};
const config = {
headerMode: 'none',
initialRouteName: 'Tab1',
defaultNavigationOptions: {
tabBarOnPress: (data) => {
// this is where the magic happens
const { navigation, defaultHandler } = data;
// we check to see if the navigation key is going to be on Tab3
if (navigation.state.key === 'Tab3') {
// if it is we show the ModalScreen by navigating to it
navigation.navigate('ModalScreen');
} else {
// otherwise we call the defaultHandler and navigate to the tab we pressed
defaultHandler(navigation.state.key);
}
}
}
};
const TabNavigator = createBottomTabNavigator(screens, config);
const stackScreens = {
Tabs: {
screen: TabNavigator
},
ModalScreen: {
screen: ModalScreen
}
};
//we need to set the mode to be modal
const stackConfig = {
headerMode: 'none',
initialRouteName: 'Tabs',
mode: 'modal'
};
const MainNavigator = createStackNavigator(stackScreens, stackConfig);
export default createAppContainer(MainNavigator);
#Screen.js
A simple screen for each tab
import React from 'react';
import { View, StyleSheet, Text } from 'react-native';
export default class Screen extends React.Component {
render () {
return (
<View style={styles.container}>
<Text>Tab Screen</Text>
</View>
);
}
}
#ModalScreen
This screen is the modal that will appear when the tab for the third screen is tapped.
As it is part of the StackNavigator, defined above, it has access to the navigation prop. We set up a simple button that when pressed calls this.props.navigation.goBack() This will dismiss the modal.
import React from 'react';
import { View, StyleSheet, Text, Button } from 'react-native';
export default class Screen extends React.Component {
render () {
return (
<View style={styles.container}>
<Text>Modal Screen</Text>
<Button
title={'close modal'}
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
Here is a snack with it working, https://snack.expo.io/@andypandy/show-modal-on-tab-press, hopefully it will show you how to set it up.