Desactivar el botón de retroceso en reaccionar navegación

85

Estoy usando react native navigation (react-navigation) StackNavigator. comienza desde la página de inicio de sesión durante todo el ciclo de vida de la aplicación. No quiero tener una opción de retroceso, volviendo a la pantalla de inicio de sesión. ¿Alguien sabe cómo se puede ocultar en la pantalla después de la pantalla de inicio de sesión? Por cierto, también lo estoy ocultando en la pantalla de inicio de sesión usando:

const MainStack = StackNavigator({
  Login: {
    screen: Login,
    navigationOptions: {
      title: "Login",
      header: {
        visible: false,
      },
    },
  },
  // ... other screens here
})
EyalS
fuente

Respuestas:

202

1) Para hacer que el botón Atrás desaparezca en react-navigation v2 o más reciente:

navigationOptions:  {
    title: 'MyScreen',
    headerLeft: null
}

2) Si desea limpiar la pila de navegación:

Suponiendo que se encuentra en la pantalla desde la que desea navegar:

Si está usando la versión de react-navigation v5 o más reciente , puede usar navigation.reseto CommonActions.reset:

 // Replace current navigation state with a new one,
 // index value will be the current active route:

navigation.reset({
  index: 0,
  routes: [{ name: 'Profile' }],
});

Fuente y más información aquí: https://reactnavigation.org/docs/navigation-prop/#reset

O:

navigation.dispatch(
  CommonActions.reset({
    index: 1,
    routes: [
      { name: 'Home' },
      {
        name: 'Profile',
        params: { user: 'jane' },
      },
    ],
  })
);

Fuente y más información aquí: https://reactnavigation.org/docs/navigation-actions/#reset

Para versiones anteriores de react-navigation:

v2-v4 usoStackActions.reset(...)

import { StackActions, NavigationActions } from 'react-navigation';

const resetAction = StackActions.reset({
  index: 0, // <-- currect active route from actions array
  actions: [
    NavigationActions.navigate({ routeName: 'myRouteWithDisabledBackFunctionality' }),
  ],
});

this.props.navigation.dispatch(resetAction);

v1 usoNavigationActions.reset

3) Para Android, también tendrá que deshabilitar el botón de retroceso del hardware con BackHandler :

http://reactnative.dev/docs/backhandler.html

o si quieres usar ganchos:

https://github.com/react-native-community/hooks#usebackhandler

de lo contrario, la aplicación se cerrará al presionar el botón Atrás del hardware Android si la pila de navegación está vacía.

Florin Dobre
fuente
4
Esto eliminará el botón de retroceso, pero en Android aún podemos navegar usando el botón de retroceso del dispositivo. ¿Hay alguna forma de desactivar eso también?
Gokul Kulkarni
2
Eres el rey
Dimitris Filippou
3
Y cuando esté en 2018 use "StackAction.reset (...)" en lugar de "NavigationActions.reset (...)", consulte reactnavigation.org/docs/en/stack-actions.html
Manuel
1
"No se puede leer la clave de indefinido" cuando se utiliza "índice: 1". Entonces, para corregir este error, utilizo "index: 0". Creo que tiene sentido
Mauricio Pastorini
1
Parece que la API se mejoró nuevamente, al menos en la v5 ahora hay una forma más corta de hacer esa acción de restablecimiento: reactnavigation.org/docs/navigation-prop#reset
AndyO
34

¿Ha considerado usar en this.props.navigation.replace( "HomeScreen" )lugar de this.props.navigation.navigate( "HomeScreen" ).

De esta manera, no está agregando nada a la pila. por lo que HomeScreen no agitará nada para volver si se presiona el botón Atrás en Android o la pantalla se desliza hacia la derecha en IOS.

Más información consulte la Documentación . Y, por supuesto, puede ocultar el botón de retroceso mediante el establecimiento headerLeft: nulldenavigationOptions

Tarik Chakur
fuente
no puede pasar parámetros usando reemplazar.
Deepak Pathak
17

Puede ocultar el botón de retroceso usando left:null, pero para los dispositivos Android, aún puede retroceder cuando el usuario presiona el botón de retroceso. Necesita restablecer el estado de navegación y ocultar el botón conleft:null

Aquí están los documentos para restablecer el estado de navegación: https://reactnavigation.org/docs/navigators/navigation-actions#Reset

Esta solución funciona react-navigator 1.0.0-beta.7, sin embargo, left:nullya no funciona para la última versión.

JXLai
fuente
5
en iOS aún puede deslizarse desde el borde de la pantalla para volver a aparecer. Definitivamente es necesario restablecer el estado de navegación.
Cameronmoreau
17

Necesitamos establecer falso gesturesEnabledjunto con headerLeftto null. Porque también podemos navegar hacia atrás deslizando la pantalla.

navigationOptions:  {
   title: 'Title',
   headerLeft: null,
   gesturesEnabled: false,
}
Gavidi Harikrishna
fuente
9

usar BackHandler de react native funcionó para mí. Simplemente incluya esta línea en su ComponentWillMount:

BackHandler.addEventListener('hardwareBackPress', function() {return true})

deshabilitará el botón de retroceso en el dispositivo Android.

OsamaD
fuente
Esto es solo para Android.
georgiosd
4

lo encontré yo mismo;) agregando:

  left: null,

desactivar el botón de retroceso predeterminado.

const MainStack = StackNavigator({
  Login: {
    screen: Login,
    navigationOptions: {
      title: "Login",
      header: {
        visible: false,
      },
    },
  },
  FirstPage: {
    screen: FirstPage,
    navigationOptions: {
      title: "FirstPage",
      header: {
        left: null,
      }
    },
  },
EyalS
fuente
4

versiones de react-navigation> = 1.0.0-beta.9

navigationOptions:  {
   headerLeft: null
}
Vaibhav KB
fuente
3

La mejor opción para manejar esta situación es utilizar SwitchNavigator proporcionado por React navigation . El propósito de SwitchNavigator es mostrar solo una pantalla a la vez. De forma predeterminada, no maneja acciones de retroceso y restablece las rutas a su estado predeterminado cuando se cambia. Este es el comportamiento exacto que se necesita en el flujo de autenticación.

Esta es una forma típica de implementarlo.

  1. Cree 2 navegadores de pila: uno para la autenticación (iniciar sesión, registrarse, olvidó la contraseña, etc.) y otro para la aplicación principal
  2. Cree una pantalla en la que verifique qué ruta desde el navegador de cambio desea mostrar (generalmente verifico esto en la pantalla de inicio verificando si un token está almacenado en el almacenamiento Async)

Aquí hay una implementación de código de las declaraciones anteriores

import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import HomeScreen from "./homeScreenPath" 
import OtherScreen from "./otherScreenPath"
import SignInScreen from "./SignInScreenPath" 
import SplashScreen from "./SplashScreenPath"

const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });

const AuthStack = createStackNavigator({ SignIn: SignInScreen });


export default createAppContainer(
  createSwitchNavigator(
    {
      Splash: SplashScreen,
      App: AppStack,
      Auth: AuthStack,
    },
    {
      initialRouteName: 'Splash',
    }
  )
);

Ahora, en SplashScreen, comprobará el token y navegará en consecuencia

import React from 'react';
import {
  ActivityIndicator,
  AsyncStorage,
  StatusBar,
  StyleSheet,
  View,
} from 'react-native';

class SplashScreen extends React.Component {
  componentDidMount() {
    this.checkIfLogin();
  }

  // Fetch the token from storage then navigate to our appropriate place
  checkIfLogin = async () => {
    const userToken = await AsyncStorage.getItem('userToken');

    // This will switch to the App screen or Auth screen and this splash
    // screen will be unmounted and thrown away.
    this.props.navigation.navigate(userToken ? 'App' : 'Auth');
  };

  // Render any loading content that you like here
  render() {
    return (
      <View>
        <ActivityIndicator />
        <StatusBar barStyle="default" />
      </View>
    );
  }
}

Una vez que cambia las rutas en SwitchNavigator, elimina la ruta anterior automáticamente y, por lo tanto, si presiona el botón Atrás, ya no lo llevará a las pantallas de autenticación / inicio de sesión.

Hadi Mir
fuente
2

Podemos solucionarlo configurando headerLeft en nulo

static navigationOptions =({navigation}) => {
    return {
        title: 'Rechercher une ville',
        headerLeft: null,
    }  
}
Klaudia Brysiewicz
fuente
1

El SwitchNavigator sería la manera de lograr esto. SwitchNavigatorrestablece las rutas predeterminadas y desmonta la pantalla de autenticación cuando navigatese invoca la acción.

import { createSwitchNavigator, createStackNavigator, createAppContainer } from 'react-navigation';

// Implementation of HomeScreen, OtherScreen, SignInScreen, AuthLoadingScreen
// goes here.

const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = createStackNavigator({ SignIn: SignInScreen });

export default createAppContainer(createSwitchNavigator(
  {
    AuthLoading: AuthLoadingScreen,
    App: AppStack,
    Auth: AuthStack,
  },
  {
    initialRouteName: 'AuthLoading',
  }
));

Después de que el usuario vaya a SignInScreen e ingrese sus credenciales, usted debe llamar

this.props.navigation.navigate('App');
Scott Davis
fuente
1

Simplemente haciendo

headerLeft: null

podría estar obsoleto en el momento en que lea esta respuesta. Deberías usar lo siguiente

   navigationOptions = {
        headerTitle : "Title",
        headerLeft : () => {},
    }
Mohammad Sadiq
fuente
1

Para la última versión de React Navigation 5 con Typecript:

<Stack.Screen
    name={Routes.Consultations}
    component={Consultations}
    options={{headerLeft: () => null}}
  />
YACINE
fuente
1

ReactNavigation v 5.0 - Opción de pila:

options={{
headerLeft: () => { 
 return <></>; 
}
}}
Ganjargal Bolor
fuente
Por favor, describa siempre lo que está haciendo en su respuesta. Debería actualizarse o eliminarse. Lea Cómo responder antes de proporcionar más respuestas ^^
finnmglas
0

Creo que es simple, solo agregue headerLeft : null, estoy usando react-native cli, así que este es el ejemplo:

static navigationOptions = {
    headerLeft : null
};
Cevin Ways
fuente
0

Para la última versión de React Navigation, incluso si usa null en algunos casos, ¡todavía puede mostrar "back" escrito!

Busque esto en su app.js principal bajo su nombre de pantalla o simplemente vaya a su archivo de clase y agregue: -

static navigationOptions = {
   headerTitle:'Disable back Options',
   headerTitleStyle: {color:'white'},
   headerStyle: {backgroundColor:'black'},
   headerTintColor: 'red',
   headerForceInset: {vertical: 'never'},
   headerLeft: " "
}
Rishav Kumar
fuente
0

En la última versión (v2) funciona headerLeft:null. puedes agregar el controlador navigationOptionscomo abajo

static navigationOptions = {
    headerLeft: null,
};
tarikul05
fuente
0

Para react-navigation versión 4.x

navigationOptions: () => ({
      title: 'Configuration',
      headerBackTitle: null,
      headerLayoutPreset:'center',
      headerLeft: null
    })
Lovekush Vishwakarma
fuente
0
headerLeft: null

Esto no funcionará en la última versión nativa de react

Debería ser:

navigationOptions = {
 headerLeft:()=>{},
}

Para mecanografiado:

navigationOptions = {
 headerLeft:()=>{return null},
}
asim mehmood
fuente