2

I have a custom TabBar for a Tab.Navigator that needs to have a different action when one of the tabs is selected based on what the current route is in the Stack Navigator component for that tab.

How can I inspect the currently displayed Stack.Screen inside of this custom TabBar? Trying to use the getRoute hook only shows me the parent screen that hosts that Tab.Navigator.

<Tab.Navigator tabBar={(props) => <BottomTabBar {...props} />}>
      <Tab.Screen
        name="Home"
        component={HomeStack}
        initialParams={{showSuccess: route.params?.showSuccess}}
      />
      <Tab.Screen name="Alternate" component={AlternateScreen} />
    </Tab.Navigator>

I can't pass the value in using tabBarOptions as I don't know what the selected route would be when the tab bar is created.

airowe
  • 794
  • 2
  • 9
  • 29
  • I ended up keeping track of the current screen outside the scope of the navigator, but will leave this open in case someone has a better solution. – airowe Aug 05 '20 at 14:52
  • That seems like a good solution to me. You can add it as an answer. – 5eb Aug 05 '20 at 14:54

2 Answers2

1

I ended up keeping track of the current screen outside the scope of the navigator as the built in Tab Navigator did not keep a reference to nested screens in a Stack Navigator like I was hoping it would.

Only needing to determine a difference between two screens, my crude hack was to have a current screen reference in a context hook and update that value in a useEffect hook when the relevant screen was mounted.

In whatever your provider is, have a currentScreen const like this:

const currentScreen = useRef('Closet');

Then, in your screens, destructure that value from the provider in the useContext hook:

const { currentScreen } = useContext(MyContext);

Then, in the same screen update that currentScreen value in a useEffect hook:

useEffect(() => {
    currentScreen.current = 'NewScreen';
}, []);
airowe
  • 794
  • 2
  • 9
  • 29
1

just figured this out for ReactNavigation v6+

i use:

const Tab = createMaterialTopTabNavigator();

and then:

<Tab.Navigator 
   initialRouteName={'Tab-All'}
   screenOptions={screenOptions}
   screenListeners={{state: (e) => { currentTabIndex.current = e.data.state.index }}}
   initialLayout={{width, height}}
>
... // your screens go here
</Tab.Navigator>

CurrentTabIndex is just variable created by useRef So as you might figure Tab.Navigator inherits some Navigator properties.

user2634449
  • 114
  • 1
  • 6