Search code examples
react-nativereact-navigationreact-navigation-stackreact-navigation-v5react-navigation-bottom-tab

React Navigation v.5 Tab Bar Icon Navigate to Modal


Anyone know a good alternative to tabBarOnPress in react navigation v.5? I want to navigate to a modal stack when a user presses a tabIcon, (i.e. cancel its default navigation behavior) but the icon seems to navigate to the Tab Screen first, then navigates to the modal.

For clarification, here is my PostIcon TabIcon Component

export const PostStackIcon: React.FC<TabBarIconProps> = ({ size, color }) => {
    const navigation = useNavigation();

    const goToCreatePost = () => {
        navigation.navigate('CreatePostStack', { screen: 'CreatePost'});
    }

    return (
        <TouchableWithoutFeedback onPress={() => goToCreatePost()}>
            <Icon
                name="Post"
                width={size * 2}
                height={size}
                fillOpacity={0}
                stroke={color} 
                secondaryStroke={color}
            />
        </TouchableWithoutFeedback>
    )
}

Solution

  • Official document

    You can use listeners prop of Tab.Screen, this is the closest alternative to tabBarOnPress IMHO.

    Below is quoted from the documents:

    Sometimes you might want to add a listener from the component where you defined the navigator rather than inside the screen. You can use the listeners prop on the Screen component to add listeners. The listeners prop takes an object with the event names as keys and the listener callbacks as values.

    Example:

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

    You can also pass a callback which returns the object with listeners. It'll receive navigation and route as the arguments.

    Example:

    <Tabs.Screen
      name="Chat"
      component={Chat}
      listeners={({ navigation, route }) => ({
        tabPress: e => {
          // Prevent default action
          e.preventDefault();
    
          // Do something with the `navigation` object
          navigation.navigate('AnotherPlace');
        },
      })}
    />