React Navigation - navigation.navigate() no navega usando la ventana s

React Navigation - navigation.navigate() no navega usando la ventana superior

Utilizo la siguiente estructura en mi proyecto React Native.

<NavigationContainer>
  <Stack.Navigator>
    <Stack.Screen name="Login" component={LoginScreen} />
    <Stack.Screen
      name="Home"
      component={HomeScreen}
      options={{
        headerRight: () => <SettingsButton />,
        presentation: 'modal',
      }}
    />
    <Stack.Screen
      name="Settings"
      component={SettingsScreen}
      options={{
        presentation: 'card',
      }}
    />
  </Stack.Navigator>
</NavigationContainer>

function SettingsButton() {
  const navigation = useNavigation();

  return (
    <Button 
      title="Settings" 
      onPress={() => navigation.navigate('Settings')} 
    />
  );
}

Cada vez que se presiona el botón de configuración, quiero abrir mi ventana de configuración en la pantalla de inicio (ventana de primer plano) y no en la pantalla de inicio de sesión (ventana de fondo/raíz). Desafortunadamente, React Navigation usa la ventana raíz para empujar la pantalla y esto sucede (observe cómo aparece el botón Atrás en la ventana de fondo):

captura de pantalla de las dos ventanas

¿Cómo puedo hacer que use la ventana de primer plano?

Mostrar la mejor respuesta

está presentando como modal para la pantalla de inicio y tarjeta para la pantalla de configuración. entonces aparecerá solo así ... ¿cuál es su requisito exacto? en realidad tu pregunta es un poco confusa.

@Manojkanth El problema es que el empuje de navegación no ocurre en la pantalla modal abierta, sino en la pantalla en segundo plano.

Desde su pantalla de inicio en el modal, ¿ha intentado descartar su modal antes de presionar la vista de su tarjeta (pantalla de configuración)?

@Manojkanth No quiero hacer eso, quiero pasar a la pila de navegación en la pantalla que se muestra modalmente.

Creo que no puedes empujar una pantalla dentro del modal ... si quieres abrir un modal sobre modal, entonces es posible. Si desea abrir una pantalla de configuración dentro del modal, debe usar esa pantalla de configuración como un componente.

@Manojkanth ¿Estás seguro de eso? Esto parece una cosa bastante crucial que falta.

sí ... me enfrenté a un problema similar como este antes.

Tu diseño de ux me parece un poco jodido aquí. ¿Por qué intentaría abrir la configuración en la pantalla de inicio? La pantalla de inicio es para su contenido y no debería tener nada que ver con la configuración cuando los separa claramente. ¿Y por qué tendrías una pantalla de inicio como modal? Eso es realmente confuso. Haga que su pantalla de inicio sea predeterminada y la pantalla de configuración como modal para superponer el resto como lo haría en cada flujo normal

Tu pantalla de inicio es un modal y la pantalla de configuración es un card e intentaste abrir la pantalla de la tarjeta dentro de la pantalla modal, no es posible, o tienes que configurar configuración como un modal, para que aparezca en la parte superior de la pantalla de inicio o establezca la Home como un card, para que no aparezca en la parte superior de la pantalla de configuración.

"para que no aparezca en la parte superior de la pantalla de configuración". ¿Te refieres a la pantalla de inicio de sesión?

Avatar Guy
Respuesta aceptada

Nota: aquí hay un problema aparte que puede causarle problemas en el futuro. He añadido una descripción a continuación.

Con respecto a la pregunta que nos ocupa, ¿qué tal pasar una pila al modal?

export const Root = () => {
    const RootStack = useMemo(() => createStackNavigator(), []);
    const HomeStack = useMemo(() => createStackNavigator(), []);

    function renderHomeStack() {
        return (
            <HomeStack.Navigator>
                <HomeStack.Screen name="Home" component={HomeScreen} />
                <HomeStack.Screen name="Settings" component={SettingsScreen} />
            </HomeStack.Navigator>
        );
    }

    function renderRootStack() {
        return (
            <RootStack.Navigator>
                <RootStack.Screen name="Login" component={LoginScreen} />
                <RootStack.Screen
                    name="HomeStack"
                    options={{
                        presentation: 'modal',
                    }}
                    component={renderHomeStack}
                />
            </RootStack.Navigator>
        );
    }

    return renderRootStack();
};

Puedes notar que react-navigation fomenta la separación de la pila de inicio de sesión y la pila principal. Puedes leer más sobre esto aquí. Si no lo hace, es posible que encuentre varios problemas en el futuro, como:

  1. Bloquear el botón Atrás en Android para evitar volver a la página de inicio de sesión después de un inicio de sesión exitoso.
  2. Restablecer el estado de navegación para navegar más fácilmente a las páginas internas con navigate:
    navigation.navigate('Root', { screen: 'Profile' });
    
  3. Implementación de enlaces profundos en el camino para navegar en función de una notificación automática.

La conclusión es que implementar navigation es considerablemente más fácil cuando las pilas están separadas.

Terminé usando esta respuesta con esto: reactnavigation.org/docs/preventing-going-back