Search code examples
reactjsreact-nativereact-navigationreact-navigation-stackreact-navigation-v6

Adding TabBarBadge value with createNativeStackNavigator and useNavigation


I am trying to change tabBarBadge value from Stack react-navigation:

import React from 'react';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { NavigationContainer } from '@react-navigation/native';
import { MaterialCommunityIcons } from '@expo/vector-icons';
//screens
import SummaryReportsScreen from './screens/SummaryReportsScreen';
import CreateReportsScreen from './screens/CreateReportsScreen';

const HomeStackNavigator = createNativeStackNavigator();

function MyStack() {
    return(
        <HomeStackNavigator.Navigator
        initialRouteName='SummaryReports'>
            <HomeStackNavigator.Screen
                name='SummaryReports'
                component={SummaryReportsScreen}>

            </HomeStackNavigator.Screen>

            <HomeStackNavigator.Screen
                name='CreateReports'
                component={CreateReportsScreen}>

            </HomeStackNavigator.Screen>

        </HomeStackNavigator.Navigator>
    )
}

const Tab = createBottomTabNavigator();

function MyTabs() {
    return (
        <Tab.Navigator>
            <Tab.Screen 
                name='Summary Reports' 
                component={MyStack}
                options={{
                    tabBarIcon: ({color, size}) =>(
                        <MaterialCommunityIcons name="calendar" size={size} color={color} />
                    ),
                    headerShown: false,
                    tabBarBadge: 5
                }}>

            </Tab.Screen>
            <Tab.Screen 
                name='Create Reports' 
                component={CreateReportsScreen}
                options={{
                    tabBarIcon: ({color, size}) =>(
                        <MaterialCommunityIcons name="file-document-edit-outline" size={size} color={color} />
                    )
                }}>
            </Tab.Screen>
        </Tab.Navigator>
    );
}

export default function Navigation() {
    return (
        <NavigationContainer>
            <MyTabs/>
        </NavigationContainer>
    );
}

So, when I am in the SummaryReports Screen i try to change it in useLayoutEffect

import React, { useState, useLayoutEffect } from 'react';
import { useNavigation, useFocusEffect } from '@react-navigation/native';

export default function SummaryReportsScreen(props) {
const [reportesNot, setReportesNot] = useState(0);
.....
const navigation = useNavigation();

  useLayoutEffect(() => {
    navigation.setOptions({
      tabBarBadge: reportesNot,
    });
  }, [reportesNot])

When i was not using MyStack as Root component to change navigation it worked with:

....

  useLayoutEffect(() => {
    props.navigation.setOptions({
      tabBarBadge: reportesNot,
    });
  }, [reportesNot])

Thanks in advance


Solution

  • How i fixed:

    Reading docs from reactnavigation theres a method returns the navigation prop from the parent navigator that the current navigator is nested in. More info:

    https://reactnavigation.org/docs/navigation-prop/#getparent

      useLayoutEffect(() => {
        navigation.getParent().setOptions({
          tabBarBadge: reportesNot,
        });
      }, [reportesNot])
    

    using getParent() will allow us to modify the tabBarBadge from parent stack navigator