11

In my react native app, I have a router component which uses react-navigation-material-bottom-tabs.

In that component I have created it like this.

const tabNavigator = createMaterialBottomTabNavigator({
  home: {
    screen: Home,
    navigationOptions: ({ navigation }) => ({
        title: ''
    })
  },
  createCampaign: {
    screen: CreateCampaign,
    navigationOptions: ({ navigation }) => ({
        title: '',
        tabBarVisible: false
    })
  },
  settings: {
    screen: AllSettings,
    navigationOptions: ({ navigation }) => ({
        title: ''
    })
  }
});

This is working fine. But I want to disable some tabs of this bar under some conditions. As example, if the profile hasn't been approved, disable the tab to settings. Is there any way to do this in my screens?(Better if it's not in the router because I can't send a API request in router). How can I access tabBar options in screens? How to disable tabs? Please help.

Buwaneka Sudheera
  • 1,277
  • 4
  • 17
  • 35

5 Answers5

27

For Version 5.x there's a new way to do it.

<Tabs.Screen
  name="Chat"
  component={Chat}
  listeners={{
    tabPress: e => {
      // Prevent default action
      e.preventDefault();
    },
  }}
/>

Here's the reference link to the docs: https://reactnavigation.org/docs/navigation-events/

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Franco Petra
  • 688
  • 7
  • 18
  • Any way to disable the ripple effect – Rajendran Nadar Oct 28 '20 at 10:41
  • I think adding a transparent `pressColor` should do it. Let me know to update the answer: `````` To take into account: `pressColor - Color for material ripple (Android >= 5.0 only).` – Franco Petra Oct 28 '20 at 15:07
  • Thank you I was looking for to make the popup on last tab and that worked for me now I am able to open the popup and the tab is not opening the tab screen but I am still adding component to that tab is their any way I can remove the component prop –  Jan 13 '21 at 18:23
  • 1
    Thank you, you saved my day. This is exactly I wanted. – Muhammad Haroon Iqbal Sep 18 '21 at 09:30
5

What are you using for global state management inside your app, please store the status weather profile is approved or not inside your global state. Then you can override tabBarOnPress to check if user is approved and perform the actions accordingly, code snippet below.

const Tab_Navigator = createBottomTabNavigator({
First:{
    screen: First,
},
Second:{
    screen: Second,
},
Third:{
    screen: Third,
}
}, defaultNavigationOptions: ({ navigation }) => ({
  tabBarOnPress: ({ navigation, defaultHandler }) => {
    if (
      navigation.state.routeName === "Second" ||
      navigation.state.routeName === "Third"
    ) {
      return null;
    }
    defaultHandler();
  },})
Imjaad
  • 588
  • 3
  • 12
  • This answer helped me. I was able to pass a prop to router. Considering the value of that prop, I used your code to disable the tabs. Thanks. – Buwaneka Sudheera Mar 14 '20 at 15:13
0

You can try with tabBarComponent props available in the second parameter for createBottomTabNavigator.

You can enable or disable button as you like but please look at the note below.

I used native base Footer, you can use your preferred components.

import { Footer, FooterTab } from 'native-base'  
  const HomeScreen = createBottomTabNavigator(
        {
    First:{
        screen: First,
    },
    Second:{
        screen: Second,
    },
    Third:{
        screen: Third,
    }
      },
      {
        tabBarComponent: props => {
          return (
            <Footer>
              <FooterTab>
                <Button
                  vertical
                  active={props.navigation.state.index === 0}
                  onPress={() => props.navigation.navigate(actions.First)}
                >
                </Button>
                <Button
                  vertical
                  active={props.navigation.state.index === 1}
                  onPress={() => props.navigation.navigate(actions.Second)}
                >
                </Button>
                <Button
                  vertical
                  active={props.navigation.state.index === 2}
                  onPress={() => props.navigation.navigate(actions.Third)}
                >
                </Button>
              </FooterTab>
            </Footer>
          )
        }
      }
    )

Note: If you want to dynamically change your buttons(tab bars elements) you can not do it as these buttons are assigned on the basis of the index.

HungrySoul
  • 1,151
  • 2
  • 17
  • 31
0

I am Working on the old Project there used React-Navigation version 4.
The Solution that worked for me is follow ....

Home: {
    screen: HomeStack,
    navigationOptions: {
      tabBarOnPress:()=>{
         return null;
       },
      tabBarLabel: "Home",
      tabBarOptions: {
        activeTintColor: "#455BE0",
        inactiveTintColor: "gray",
      },
      tabBarIcon: ({ tintColor }) => (
        <Image
          style={{ height: 25, width: 25, tintColor: tintColor, marginTop: 10 }}
          source={require("./src/assets/home.png")}
        />
      ),
    },
  },

You can check in the navigationOptions added tabBarOnPress which return value is null.
This solution work for me Hope work for you also.

Saurabh Chavan
  • 136
  • 2
  • 5
0

You can overwrite tabBarButton​ using Pressable or Button component and add a conditional in order to disable the button. Something like this :

<Stack.Screen
      name="YourScreen"
      options={{
        tabBarButton: (props) => (
          <Pressable
            {...props}
            isDisabled={conditional ? true : false}
          />
        ),
      }}
      component={YourComponent}
    />