How can I dynamically load React component based on the current BottomTab Screeb that is open?

30 Views Asked by At

I have an IconButton that currently allows the user to add an expense by navigating them to the 'ManageExpense' component. I have added a new BottomTab that displays Income. There are now 3 BottomTab (RecentExpenses, AllExpenses, AllIncome).

I want to change the add expenses IconButton so that if the user is on the AllIncome BottomTab screen and they press the button, they are directed to the ManageIncome component, if they are on the RecentExpenses or AllExpenses BottomTab screen then it navigates them to the ManageExpense component.

import ManageExpense from './screens/ManageExpense';
import RecentExpenses from './screens/RecentExpenses';
import AllExpenses from './screens/AllExpenses';
import { GlobalStyles } from './constants/styles';
import IconButton from './components/UIElements/IconButton';
import ExpensesContextProvider from './context/expensesContext';
import AllIncome from './screens/AllIncome';
import { IncomeContextProvider } from './context/incomeContext';
import ManageIncome from './screens/ManageIncome';

const Stack = createNativeStackNavigator();
const BottomTabs = createBottomTabNavigator();

function ExpensesOverview() {

  
  return (
    <BottomTabs.Navigator screenOptions={({ navigation }) => ({

      headerStyle: { backgroundColor: GlobalStyles.colors.primary500 },
      headerTintColor: 'white',
      tabBarStyle: { backgroundColor: GlobalStyles.colors.primary500 },
      tabBarActiveTintColor: GlobalStyles.colors.accent500,
      headerRight: ({ tintColor }) => (
        <IconButton
          icon="add-circle-outline"
          size={26} color={tintColor}
          onPress={() => {
            navigation.navigate('ManageExpense');
          }}>
        </IconButton>
      ),
    })}
    >
      <BottomTabs.Screen
        name="RecentExpenses"
        component={RecentExpenses}
        options={{
          title: 'Recent Expenses',
          tabBarLabel: 'Recent Expenses',
          tabBarIcon: ({ color, size }) => (
            <Ionicons name="time-outline" size={size} color={color} />
          ),
        }}
      />
      <BottomTabs.Screen
        name="AllExpenses"
        component={AllExpenses}
        options={{
          title: 'All Expenses',
          tabBarLabel: 'All Expenses',
          tabBarIcon: ({ color, size }) => (
            <Ionicons name="globe-outline" size={size} color={color} />
          ),
        }}
      />
      <BottomTabs.Screen
        name="AllIncome"
        component={AllIncome}
        options={{
          title: 'All Income',
          tabBarLabel: 'View Income',
          tabBarIcon: ({ color, size }) => (
            <Ionicons name="cash-outline" size={size} color={color}></Ionicons>
          ),
        }}
      />
    </BottomTabs.Navigator>
  );
}

export default function App() {
  return (
    <>
      <StatusBar style="auto" />
      <ExpensesContextProvider>
        <IncomeContextProvider>
          <NavigationContainer>
            <Stack.Navigator screenOptions={{
              headerStyle: { backgroundColor: GlobalStyles.colors.primary500 },
              headerTintColor: 'white',
              headerBackTitle: 'Back',
            }}>
              <Stack.Screen
                name="ExpensesOverview"
                component={ExpensesOverview}
                options={{ headerShown: false }}
              />
              <Stack.Screen
                name="ManageExpense"
                component={ManageExpense}
                options={{
                  presentation: 'modal',
                }} />
                 <Stack.Screen
                name="ManageIncome"
                component={ManageIncome}
                options={{
                  presentation: 'modal',
                }} />
            </Stack.Navigator>
          </NavigationContainer>
        </IncomeContextProvider>
      </ExpensesContextProvider>
    </>
  );
};

I have tried using the useRoute() function but it seems to only return the 'ExpensesOverview' value, so it doesn't differentiate between the different BottomTabs but I may be using it wrong... Thanks.

1

There are 1 best solutions below

1
user18309290 On BEST ANSWER

One way to update the header is to use options in specific Screen. Like below headerRight is updated in HomeScreen.

<Tab.Navigator
  screenOptions={({ navigation, route }) => ({
    headerRight: () => <Button title="Default" />,
  })}>
  <Tab.Screen
    name="Home"
    component={HomeScreen}
    options={({ navigation, route }) => ({
      headerRight: () => <Button title="Update" />,
    })}
  />
  <Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>