reactjsreact-nativereact-navigationreact-navigation-bottom-tab

React Navigation tabPress does not include preventDefault


I am attempting to suppress the default actions of a Tab, and display a modal instead of a screen.

package.json

"@react-navigation/bottom-tabs": "6.5.11",
"@react-navigation/drawer": "6.6.2",
"@react-navigation/native": "6.1.6",
"@react-navigation/stack": "6.2.0",

TabNavigation.js

import React, { useEffect } from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

export default function TabNavigation() {
  useEffect(() => {
    return navigation.addListener('tabPress', (e) => {
      console.log('addListener', e);
      // Prevent default behavior
      e.preventDefault();

      // Do something manually
      // ...
    });
  }, [navigation]);

... 

  return (
    <Navigator
      initialRouteName='InboxTab'
      path='dialer'
      tabBar={renderTabBar}
      screenOptions={{
        allowFontScaling: false,
        headerShown: false,
      }}
    >
      <Screen
        name='MenuTab'
        component={RenderMenuIcon}
        options={({ route }) => {
          return {
            tabBarLabel: i18n('Menu'),
            tabBarIcon: RenderMenuIcon,
            tabBarVisible: setTabBarVisible(route),
          };
        }}
        listeners={({ navigation, route }) => ({
          tabPress: (e) => {
            console.log(e);
            // Prevent default action
            e.preventDefault();

            // Do something with the `navigation` object
            navigation.openDrawer();
          },
        })}
      />
    </Navigator>
  );
}

The issue I am getting is e.preventDefault() is undefined the console output is {target: "MenuTab-7dSuEnww56CNR3M4Cls8V", type: "tabPress"}

I have been looking through these docs: https://reactnavigation.org/docs/navigation-events/#listeners-prop-on-screen but have not had any luck on solving why the tabPress is being called but not getting a preventDefault function to appear in the logs.

Any thoughts or ideas would be greatly appreciated!


Solution

  • You're using a custom tab bar component. It's upto you to implement the event properly. For preventDefault to be available, you need to pass canPreventDefault: true.

    Here is an example from the docs:

    const event = navigation.emit({
      type: 'tabPress',
      target: route.key,
      canPreventDefault: true,
    });
    
    if (!isFocused && !event.defaultPrevented) {
      navigation.navigate(route.name, route.params);
    }
    

    https://reactnavigation.org/docs/bottom-tab-navigator/#tabbar