React Navigation how to hide tabbar from inside st

2020-05-21 06:06发布

问题:

I have the following stack navigation and screens:

export const HomeStack = createStackNavigator({
    Home: HomeScreen,
    Categories: CategoriesScreen,
    Products: ProductsScreen,
    ProductDetails: ProductDetailsScreen,
})

I want to hide tabs only in ProductDetailsScreen

export const hideTabBarComponents = [
    'ProductDetails',
]

export const MainTabs = createBottomTabNavigator(
    {
        Home: HomeStack,
        Favorite: FavoriteScreen,
        Account: AccountScreen,
        Help: HelpScreen,
        Events: EventsScreen
    },
    {
        navigationOptions: ({ navigation }) => ({

            tabBarIcon: ({ focused, tintColor }) => {
                ...
            },
            tabBarLabel: ({ focused, tintColor }) => {
                ...
            },

            tabBarVisible: ! hideTabBarComponents.includes(navigation.state.routeName)

        }),
    }
);

The problem that can't pass any options to Tab navigation from Stack Navigation

Not all of the stack screens only one of them

回答1:

After a little search, The following code solved the problem:

HomeStack.navigationOptions = ({ navigation }) => {

    let tabBarVisible = true;

    let routeName = navigation.state.routes[navigation.state.index].routeName

    if ( routeName == 'ProductDetails' ) {
        tabBarVisible = false
    }

    return {
        tabBarVisible,
    }
}


回答2:

For React Navigation 5, you can do this inside of the stack component:

props.navigation.dangerouslyGetParent().setOptions({
  tabBarVisible: false
});

https://reactnavigation.org/docs/en/navigation-prop.html#setoptions---update-screen-options-from-the-component

Be careful with using this though, you'll want to reset the tabBarVisible to true once unmounting the component.

For example, with React hooks inside the Stack component:

    useEffect(() => {
      const parent = props.navigation.dangerouslyGetParent();
      parent.setOptions({
        tabBarVisible: false
      });
      return () =>
        parent.setOptions({
          tabBarVisible: true
        });
    }, []);

Or you can reset the tabBarVisible in the Stack.Screen component with the back button press like this:

    const StackNav = (props) => (
      <Stack.Screen
        name='name'
        component={Name}
        options={{
          headerTitle: 'Name',
          headerLeft: () => (
            <Text
              onPress={() =>
                props.navigation.setOptions({
                tabBarVisible: true
                })
              }
            >
              on back
            </Text>
          )
        }}
      />
    }

(The second approach works better.)



回答3:

With createBottomTabNavigator you can hide it with the defaultNavigationOptions

defaultNavigationOptions: {
  tabBarVisible: false,
},


回答4:

first let's creat a stack navigator and call it StackHome

const StackHome = createStackNavigator(
{
 Home: Home,
 CustomHide: CustomHide,
});
// This code let you hide the bottom app bar when "CustomHide" is rendering
StackHome.navigationOptions = ({ navigation }) => {
 let tabBarVisible;
  if (navigation.state.routes.length > 1) {
navigation.state.routes.map(route => {
  if (route.routeName === "CustomHide") {
    tabBarVisible = false;
  } else {
    tabBarVisible = true;
  }
});
 }

 return {
   tabBarVisible
 };
};
export default StackHome;


回答5:

This is how I did. Select the stack in which you want to hide the tab bar. You can select it based on the index.

AppStack.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
    if (navigation.state.index > 0) {
       tabBarVisible = false;
    }
    return {
       tabBarVisible
    };
};

Here is the link of the docs of React navigation



回答6:

This is the solution that I used in my project.

I have a bottom tab navigator, with 2 routes: Home and Profile. The ProfileHomePage route brings to a stack navigation ProfileStackNavigation.

Then, in the ProfileStackNavigation, I have the ProfileHomePage where the bottom tab should appears, and other child pages, where the bottom tabs should not be visible. I added a param tabBarVisible: false in that pages.

Finally, in the MainTabNavigator ProfileHomePage route, I added the navigationOptions function, to test if the current route has the param tabBarVisible.

const ProfileStackNavigation = createStackNavigator(
  {
    ProfileHomePage: ProfileHomePage,
    AboutAppPage: {screen: AboutAppPage, params: {tabBarVisible: false}},
    DiaryPage: {screen: DiaryPage, params: {tabBarVisible: false}},
    FilesPage: {screen: FilesPage, params: {tabBarVisible: false}},
    NotificationsPage: {screen: NotificationsPage, params: {tabBarVisible: false}},
  },
  {
    initialRouteName: 'ProfileHomePage',
  },
);

const MainTabNavigator = createBottomTabNavigator(
  {
    HomePage: HomePage,
    ProfileHomePage: {
      screen: ProfileStackNavigation,
      navigationOptions: ({ navigation }) => {
        const {params = {}} = navigation.state.routes[navigation.state.index];
        const tabBarVisible = params.tabBarVisible === false ? params.tabBarVisible : true;
        return {
          tabBarVisible,
        }
      }
    },
  },
  {
    initialRouteName: 'HomePage',
    tabBarComponent: props => <AppFooterTab {...props} />,
  },
);