Search code examples
react-nativereact-navigationstack-navigatorreact-native-tabnavigator

Can one React Native screen be included in two different stack navigators?


Is there any reason a screen shouldn't be included in two different stack navigators?

I would like it in both stack navigators to have a smooth, in-flow page transition and back button to smoothly go back to the previous page. In example below, ContactScreen appears twice:

const StackOne = createStackNavigator({
  About: AboutScreen,
  FAQ: FAQScreen,
  Contact: ContactScreen
});

const StackTwo = createStackNavigator({
  Main: MainScreen,
  Details: DetailsScreen
  Contact: ContactScreen
});

const MainTabs = createBottomTabNavigator({
  TabOne: StackOne,
  TabTwo: StackTwo
});

Solution

  • yes, you can use the same screen in different stack navigators . follow this example:

    .js file

    import React from 'react';
    import { Button, Text, View } from 'react-native';
    import { Ionicons } from '@expo/vector-icons';
    import { createStackNavigator, createBottomTabNavigator, createAppContainer } from 'react-navigation';
    
    class HomeScreen extends React.Component {
      render() {
        return (
          <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>Home!</Text>
            <Button
              title="Go to Settings"
              onPress={() => this.props.navigation.navigate('Settings')}
            />
            <Button
              title="Go to Details"
              onPress={() => this.props.navigation.navigate('Details')}
            />
          </View>
        );
      }
    }
    
    class SettingsScreen extends React.Component {
      render() {
        return (
          <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>Settings!</Text>
            <Button
              title="Go to Home"
              onPress={() => this.props.navigation.navigate('Home')}
            />
            <Button
              title="Go to Details"
              onPress={() => this.props.navigation.navigate('Details')}
            />
          </View>
        );
      }
    }
    
    class DetailsScreen extends React.Component {
      render() {
        return (
          <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>Details!</Text>
          </View>
        );
      }
    }
    
    const HomeStack = createStackNavigator({
      Home: { screen: HomeScreen },
      Details: { screen: DetailsScreen },
    });
    
    const SettingsStack = createStackNavigator({
      Settings: { screen: SettingsScreen },
      Details: { screen: DetailsScreen },
    });
    
    export default createAppContainer(createBottomTabNavigator(
      {
        Home: { screen: HomeStack },
        Settings: { screen: SettingsStack },
      },
      {
        defaultNavigationOptions: ({ navigation }) => ({
          tabBarIcon: ({ focused, tintColor }) => {
            const { routeName } = navigation.state;
            let iconName;
            if (routeName === 'Home') {
              iconName = `ios-information-circle${focused ? '' : '-outline'}`;
            } else if (routeName === 'Settings') {
              iconName = `ios-options${focused ? '' : '-outline'}`;
            }
    
            // You can return any component that you like here! We usually use an
            // icon component from react-native-vector-icons
            return <Ionicons name={iconName} size={25} color={tintColor} />;
          },
        }),
        tabBarOptions: {
          activeTintColor: 'tomato',
          inactiveTintColor: 'gray',
        },
      }
    ));