Desative o botão Voltar na navegação de reação

87

Estou usando o StackNavigator da navegação nativa react (react-navigation). ele começa na página de Login ao longo de todo o ciclo de vida do aplicativo. Não quero ter a opção de voltar, voltando para a tela de Login. Alguém sabe como pode ficar oculto na tela após a tela de login? BTW, também estou escondendo na tela de login usando:

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

Respostas:

209

1) Para fazer o botão Voltar desaparecer no react-navigation v2 ou mais recente:

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

2) Se você deseja limpar a pilha de navegação:

Supondo que você esteja na tela a partir da qual deseja navegar:

Se você estiver usando a versão de navegação react v5 ou mais recente, pode usar navigation.resetou 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' }],
});

Fonte e mais informações aqui: https://reactnavigation.org/docs/navigation-prop/#reset

Ou:

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

Fonte e mais informações aqui: https://reactnavigation.org/docs/navigation-actions/#reset

Para versões mais antigas do react-navigation:

uso de v2-v4StackActions.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);

uso v1NavigationActions.reset

3) Para o Android, você também terá que desativar o botão Voltar do hardware usando o BackHandler :

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

ou se você quiser usar ganchos:

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

caso contrário, o aplicativo será fechado ao pressionar o botão Voltar do hardware do Android se a pilha de navegação estiver vazia.

Florin Dobre
fonte
4
Isso removerá o botão Voltar, mas no Android ainda podemos navegar usando o botão Voltar do dispositivo. Existe uma maneira de desativar isso também?
Gokul Kulkarni
2
Você é o rei
Dimitris Filippou
3
E quando você estiver em 2018, use "StackAction.reset (...)" em vez de "NavigationActions.reset (...)", consulte reactnavigation.org/docs/en/stack-actions.html
Manuel
1
"Não é possível ler a chave de indefinido" ao usar "índice: 1". Portanto, para corrigir esse erro, uso "index: 0". Acho que faz sentido
Mauricio Pastorini
1
Parece que a API foi aprimorada novamente, pelo menos na v5 agora há uma maneira mais curta de fazer essa ação de redefinição: reactnavigation.org/docs/navigation-prop#reset
AndyO
36

Você já pensou em usar em this.props.navigation.replace( "HomeScreen" )vez dethis.props.navigation.navigate( "HomeScreen" ) .

Dessa forma, você não está adicionando nada à pilha. assim, a tela inicial não acenará nada para a qual voltar se o botão voltar for pressionado no Android ou a tela for deslizada para a direita no IOS.

Mais informações consulte a Documentação . E, claro, você pode ocultar o botão de volta, definindo headerLeft: nullemnavigationOptions

Tarik Chakur
fonte
você não pode passar parâmetros usando substituir.
Deepak Pathak
18

Precisamos definir false para o gesturesEnabledjunto com headerLeftpara null. Porque também podemos navegar de volta deslizando a tela.

navigationOptions:  {
   title: 'Title',
   headerLeft: null,
   gesturesEnabled: false,
}
Gavidi Harikrishna
fonte
17

Você pode ocultar o botão Voltar usando left:null, mas para dispositivos Android, ele ainda pode voltar quando o usuário pressiona o botão Voltar. Você precisa redefinir o estado de navegação e ocultar o botão comleft:null

Aqui estão os documentos para redefinir o estado de navegação:
https://reactnavigation.org/docs/navigation-actions#reset

Esta solução funciona para react-navigator 1.0.0-beta.7, porém left:nullnão funciona mais com a versão mais recente.

JXLai
fonte
6
no iOS, você ainda pode deslizar da borda da tela para voltar. A redefinição do estado de navegação é definitivamente necessária.
cameronmoreau
11

usando o BackHandler do Reac nativo funcionou para mim. Basta incluir esta linha em seu ComponentWillMount:

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

ele irá desativar o botão Voltar no dispositivo Android.

OsamaD
fonte
Este é apenas o Android.
georgiosd
4

encontrei sozinho;) adicionando:

  left: null,

desative o botão Voltar padrão.

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

versões react-navigation> = 1.0.0-beta.9

navigationOptions:  {
   headerLeft: null
}
Vaibhav KB
fonte
3

A melhor opção para lidar com esta situação é usar o SwitchNavigator fornecido pelo React navigation . O objetivo do SwitchNavigator é mostrar apenas uma tela de cada vez. Por padrão, ele não controla as ações de volta e redefine as rotas para seu estado padrão quando você alterna. Este é o comportamento exato necessário no fluxo de autenticação.

Esta é uma maneira típica de implementá-lo.

  1. Crie 2 navegadores de pilha: um para autenticação (login, cadastro, esqueci a senha, etc) e outro para o APP principal
  2. Crie uma tela na qual você verificará qual rota do navegador do switch você deseja mostrar (geralmente eu verifico isso na tela inicial, verificando se um token está armazenado no armazenamento Async)

Aqui está uma implementação de código das declarações acima

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',
    }
  )
);

Agora em SplashScreen você irá verificar o token e navegar de acordo

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>
    );
  }
}

Depois de alterar as rotas no SwitchNavigator, ele remove a rota mais antiga automaticamente e, portanto, se você pressionar o botão Voltar, ele não o levará mais para as telas de autenticação / login

Hadi Mir
fonte
2

Podemos corrigir isso definindo headerLeft como null

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

Para a última versão do React Navigation 5 com Typescript:

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

O SwitchNavigator seria a maneira de fazer isso. SwitchNavigatorredefine as rotas padrão e desmonta a tela de autenticação quando a navigateação é invocada.

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',
  }
));

Depois que o usuário vai para SignInScreen e insere suas credenciais, você deve chamar

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

Simplesmente fazendo

headerLeft: null

pode estar obsoleto no momento em que você ler esta resposta. Você deve usar o seguinte

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

ReactNavigation v 5.0 - opção de pilha:

options={{
headerLeft: () => { 
 return <></>; 
}
}}
Ganjargal Bolor
fonte
Sempre descreva o que você está fazendo em sua resposta. Deve ser atualizado ou removido. Leia Como responder antes de fornecer mais respostas ^^
finnmglas
0

Acho que é simples, basta adicionar headerLeft : null, estou usando CLI nativo reag, então este é o exemplo:

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

Para a versão mais recente do React Navigation, mesmo se você usar null em alguns casos, ele ainda pode mostrar "back" escrito!

Faça isso em seu app.js principal sob seu nome de tela ou apenas vá para o arquivo da classe e adicione: -

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

Na versão mais recente (v2) funciona headerLeft:null. você pode adicionar controladores navigationOptionscomo abaixo

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

Para react-navigation versão 4.x

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

Isso não funcionará na última versão nativa do react

Deveria ser:

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

Para texto datilografado:

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

Nas versões 5.x do react-navigation, você pode fazer assim:

import { CommonActions } from '@react-navigation/native';

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

Você pode ler mais aqui .

Ankur Kedia
fonte