Pooja Rajendran C
Pooja Rajendran C

Reputation: 452

React native : bottom navigation with dynamic initialRouteName implementation

I am a beginner in react native. I have gone through different related topics. But failed. This is my issues,

I have a bottom navigator with 4 items, say Dashboard, X, Patient and Y. Here is the optimised bottom navigator code.

   const Stack = createStackNavigator();
   const Bottom = createBottomTabNavigator();
    const Main = () => {
    return (
      <Bottom.Navigator
        initialRouteName="DashboardScreenStack"
        tabBarOptions={{
          style: {
            height: 70,
            paddingTop: 20,
            backgroundColor: '#F3F6FF',
          },
          activeTintColor: colors.navigationTextActive,
          inactiveTintColor: colors.navigationTextInactive,
          labelStyle: {
            fontSize: 15,
            marginTop: 15,
            paddingBottom: 10,
          },
        }}>
        <Bottom.Screen
          name="DashboardScreenStack"
          component={DashboardScreenStack}
          options={{
            tabBarLabel: 'Dashboard',
          }}
        />
        <Bottom.Screen
          name="X"
          component={X}
          options={{
            tabBarLabel: 'X',
          }}
        />
        <Bottom.Screen
          name="Patient"
          component={Patient}
          options={{
            tabBarLabel: 'Patient',
          }}
        />
        <Bottom.Screen
          name="Y"
          component={Y}
          options={{
            tabBarLabel: 'Y',
          }}
        />
      </Bottom.Navigator>
    );
  };

This is my code for Patient menu.

const Patient = (props) => {
  let resultData = null;
  var initialRoute = '';
  if (
    typeof props.route.params != 'undefined' &&
    props.route.params.result != null
  ) {
    
    resultData = props.route.params.result;
    initialRoute = 'PatientDashboardScreen';
  } else {
    initialRoute = 'AddPatientScreen';
  }
  
  return (
    <Stack.Navigator
      initialRouteName={initialRoute }>
      <Stack.Screen
        name="PatientDashboardScreen"
        component={PatientDashboardScreen}
        initialParams={resultData}
        options={{headerShown: false}}
      />
      <Stack.Screen
        name="TestScreen1"
        component={TestScreen1}
        options={{headerShown: false}}
      />
      <Stack.Screen
        name="TestScreen2"
        component={TestScreen2}
        options={{headerShown: false}}
      />
      <Stack.Screen
        name="AddPatientScreen"
        component={AddPatientScreen}
        options={{headerShown: false}}
      />
    </Stack.Navigator>
  );
};

There are 4 screens that should be shown in Patient menu. Out of those if I am selecting an item in my Dashboard menu I need to open "PatientDashboardScreen". And there will be some data available in props too. But on directly clicking 'Patient' menu, I need to move to "AddPatientScreen" where no data is passed.

I tried the above code. But only the initial click works. If I am selecting from list first, the always Patient menu is showing "PatientDashboardScreen" and if I am selecting Patient menu directly first, then always "AddPatientScreen" is shown on Patient menu selection.

Any help would be greateful. Thank you

Upvotes: 1

Views: 1519

Answers (1)

Guruparan Giritharan
Guruparan Giritharan

Reputation: 16354

Based on your question You have a bottom navigator and one of the screens has a nested stack navigator.

The requirement here is to show a specific screen when pressing the bottom navigator button and redirect to a screen when opening from another screen in bottom navigator along with some parameters.

This is one way to do this.

  <Tab.Screen
    name="Hospital"
    component={HospitalView}
    options={({ navigation }) => ({
      tabBarButton: (props) => (
        <TouchableOpacity
          {...props}
          onPress={() =>
            navigation.navigate('Hospital', { screen: 'Patient' })
          }
        />
      ),
    })}
  />

You can have a custom onPress in your bottom navigator button which will use the navigate with the screen option which will take you to the specific screen.

To navigate from another screen with parameters you can use the below option

   <Button
        title="Doctor"
        onPress={() =>
          navigation.navigate('Hospital', {
            screen: 'Doctor',
            params: { name: 'Doc 1' },
          })
        }
      />

Your full code should look something similar to this

const Stack = createStackNavigator();
function Patient() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Patient Screen</Text>
    </View>
  );
}

function Doctor({route}) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Doctor Screen</Text>
      <Text>{route?.params?.name}</Text>
    </View>
  );
}

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>Home!</Text>
      <Button
        title="Doctor"
        onPress={() =>
          navigation.navigate('Hospital', {
            screen: 'Doctor',
            params: { name: 'Doc 1' },
          })
        }
      />
    </View>
  );
}

function HospitalView() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Doctor" component={Doctor} />
      <Stack.Screen name="Patient" component={Patient} />
    </Stack.Navigator>
  );
}

const Tab = createBottomTabNavigator();

function MyTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen
        name="Hospital"
        component={HospitalView}
        options={({ navigation }) => ({
          tabBarButton: (props) => (
            <TouchableOpacity
              {...props}
              onPress={() =>
                navigation.navigate('Hospital', { screen: 'Patient' })
              }
            />
          ),
        })}
      />
    </Tab.Navigator>
  );
}

You can refer this sample https://snack.expo.io/@guruparan/5f3f1d

Upvotes: 1

Related Questions