react-nativeexporeact-native-navigation

React Native nested navigation unexpected behaviour


I am using 'react-navigation/native' in an Expo managed project and I have built using 'react-navigation/native-stack' and 'react-navigation/bottom-tabs' a navigation structure as follows:

    <Stack.Navigator screenOptions={commonHeaderStyle}>
      {username && IdUser ? //If the user is not logged in its data isn't present
        <Stack.Screen
          name="DefaultLogged"
          component={TabNavigator}
          initialParams={{IdUser, username}}
          options={{headerShown: false}}
        />  
        : 
        <Stack.Screen
          name="DefaultHome"
          component={DefaultScreen}
          options={(props) => ({
            headerShown: true,
            header: () => (<HomeHeader navigation={props.navigation} />),
          })}
        />
      }
      <Stack.Screen
        name="Default"
        component={DefaultScreen}
        options={(props) => ({
          headerShown: true,
          header: () => (<HomeHeader navigation={props.navigation} />),
        })}
      />
      <Stack.Screen
        name="Logged"
        component={TabNavigator}
        initialParams={{IdUser:null, username:null}}
        options={{headerShown: false}}
      />
    </Stack.Navigator>

Where the TabNavigator is the following:

    <Tab.Navigator>
      <Tab.Screen
        name="ProfileRoot"
        component={ProfileRoot}
        initialParams={{IdUser, username}}
        options={{title: 'Perfil', headerShown: false}}
      />
      <Tab.Screen
        name="WorkersRoot"
        component={WorkersRoot}
        options={{ title: 'Trabajadores', headerShown: false}}
      />
    </Tab.Navigator>

And my ProfileRoot and WorkersRoot components are respectively:

    <Stack.Navigator screenOptions={commonHeaderStyle}>
      <Stack.Screen
        name="Profile"
        component={ProfileScreen}
        options={{title: 'Perfil'}}
      />
      <Stack.Screen
        name="UserReviews"
        component={UserReviewsScreen}
        initialParams={{ category: null, IdUser, username}}
        options={({ route }) => ({ title: `Reseñas de ${route.params.category}` })}
      />      <Stack.Screen
        name="WorkersForm"
        initialParams={{IdUser, username}}
        component={WorkerFormScreen}
        options={{title: 'Subir oficio'}}
      />
      <Stack.Screen
        name="User"
        component={UserScreen}
        initialParams={{ IdUser: null, username: null }}
        options={({ route }) => ({ title: `Perfil de ${route.params.username}`})}
      />
    </Stack.Navigator>
    <Stack.Navigator screenOptions={commonHeaderStyle}>
      <Stack.Screen
        name="WorkersCategories"
        component={CategoriesScreen}
        initialParams={{ type: 'trabajador' }}
        options={{title: 'Encontrar trabajador' }}
      />
      <Stack.Screen
        name="Workers"
        component={WorkersScreen}
        initialParams={{ category: null }}
      />
    </Stack.Navigator>

My main issue is that when I navigate to WorkersRoot and to the Workers screen, I have an action that sends me to the ProfileRoot and to the user screen with some params. Example function:

navigation.navigate('ProfileRoot', { screen: 'User',
    params: { IdUser: worker.id_user, username: worker.username }})

And when I hit the return button or press the Tab icon to send me to the first screen in the ProfileRoot stack I get correctly sent to that screen, but when I press the icon of the WorkersRoot Tab and press again the ProfileRoot Tab (to return to the Profile screen as expected, the User screen gets rendered instead. So once I have navigated to the User's screen from the WorkersRoot Tab, it seems there is no way to discard this screen from the ProfileRoot stack.

Here is a link to a video showing the bug

What I've tried: -To reset navigation using dispatch every time one gets redirected to the ProfileRoot from the WorkersRoot

Expected behaviour: navigate correctly between Tabs


Solution

  • I have accidentally fixed my issue. Refactoring the code to:

    navigation.navigate( 'User', { IdUser: worker.id_user, username: worker.username })

    Did the job. I do not why the bug arises when specifying the Tab Root.