在反应导航中禁用后退按钮


85

我正在使用react本机导航(react-navigation)StackNavigator。它从应用程序整个生命周期的“登录”页面开始。我不想返回选项,返回“登录”屏幕。有谁知道登录屏幕后如何将其隐藏在屏幕上?顺便说一句,我也使用以下命令将其隐藏在登录屏幕中:

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

Answers:


202

1)要使后退按钮在react-navigation v2或更高版本中消失:

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

2)如果您要清理导航堆栈:

假设您位于要从其导航的屏幕上:

如果您使用的是反应导航版本v5或更高版本,则可以使用navigation.resetCommonActions.reset

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

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

来源和更多信息在这里:https : //reactnavigation.org/docs/navigation-prop/#reset

要么:

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

来源和更多信息在这里:https : //reactnavigation.org/docs/navigation-actions/#reset

对于旧版本的反应导航:

v2-v4使用StackActions.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使用NavigationActions.reset

3)对于Android,您还必须使用BackHandler禁用硬件后退按钮

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

或者如果您想使用钩子:

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

否则,如果导航堆栈为空,则应用将在按android硬件后退按钮时关闭。


4
这将删除后退按钮,但在android中,我们仍然可以使用设备后退按钮进行导航。有没有办法禁用它?
Gokul Kulkarni

2
您是国王
Dimitris Filippou '17

3
而当您在2018年使用“ StackAction.reset(...)”而不是“ NavigationActions.reset(...)”时,请参见reactnavigation.org/docs/en/stack-actions.html
Manuel

1
使用“ index:1”时,“无法读取未定义的键”。因此,为了解决此错误,我使用“ index:0”。我认为这很有道理
Mauricio Pastorini '18

1
好像API又得到了改进,至少在v5中,现在有一种更短的方法来执行该重置操作: reactnavigation.org/docs/navigation-prop#reset
AndyO

34

您是否考虑过使用this.props.navigation.replace( "HomeScreen" )而不是this.props.navigation.navigate( "HomeScreen" )

这样,您就不会在堆栈中添加任何内容。因此,如果在Android中按下“后退”按钮或在IOS中向右滑动屏幕,则HomeScreen不会挥手返回任何内容。

有关更多信息,请参见文档。当然,你可以通过设置隐藏后退按钮headerLeft: nullnavigationOptions


您不能使用replace传递参数。
Deepak Pathak

17

您可以使用来隐藏后退按钮left:null,但是对于android设备,当用户按下后退按钮时,它仍然可以后退。您需要重置导航状态并使用隐藏按钮left:null

以下是用于重置导航状态的文档:https : //reactnavigation.org/docs/navigators/navigation-actions#Reset

此解决方案适用于react-navigator 1.0.0-beta.7,但left:null不再适用于最新版本。


5
在iOS上,您仍然可以从屏幕边缘滑动以弹出。确实需要重置导航状态。
cameronmoreau


9

使用React Native的BackHandler为我工作。只需在您的ComponentWillMount中添加以下行:

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

它将在Android设备上禁用后退按钮。


这仅适用于Android。
georgiosd

4

我自己找到的;)添加:

  left: null,

禁用默认的后退按钮。

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

4

react-navigation版本> = 1.0.0-beta.9

navigationOptions:  {
   headerLeft: null
}

3

解决这种情况的最佳选择是使用React导航提供的SwitchNavigator。SwitchNavigator的目的是一次只显示一个屏幕。默认情况下,它不处理后退操作,并且在您离开时将路由重置为其默认状态。这是身份验证流程中所需的确切行为。

这是实现它的典型方法。

  1. 创建2个堆栈导航器:一个用于身份验证(登录,注册,忘记密码等),另一个用于主APP
  2. 创建一个屏幕,您将在其中检查要显示的来自交换机导航器的路由(我通常在初始屏幕中通过检查令牌是否存储在异步存储中来对此进行检查)

这是上述语句的代码实现

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

现在,在SplashScreen中,您将检查令牌并进行相应导航

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

在SwitchNavigator中更改路由后,它会自动删除较旧的路由,因此,如果按“后退”按钮,它将不再带您进入“身份验证/登录”屏幕



1

SwitchNavigator将是实现这一目标的方式。调用动作SwitchNavigator时,将重置默认路由并卸载身份验证屏幕navigate

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

用户转到SignInScreen并输入其凭据后,您将调用

this.props.navigation.navigate('App');


1

对于具有Typescript的最新版本React Navigation 5:

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

1

ReactNavigation v 5.0-堆栈选项:

options={{
headerLeft: () => { 
 return <></>; 
}
}}

请务必在回答中说明您在做什么。它应该被更新或删除。在提供更多答案之前,请阅读如何回答^^
finnmglas

0

我认为这很简单,只需添加headerLeft : null,我正在使用react-native cli,所以这是示例:

static navigationOptions = {
    headerLeft : null
};

0

对于最新版本的React Navigation,即使在某些情况下使用null,也可能会显示“ back”字样!

在您的主app.js中以您的屏幕名称进行操作,或仅转到类文件并添加:-

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

0

在最新版本(v2)中工作headerLeft:null。您可以添加控制器的navigationOptions波纹管

static navigationOptions = {
    headerLeft: null,
};

0

对于反应导航版本4.x

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

0
headerLeft: null

这在最新的react native版本中不起作用

它应该是:

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

对于打字稿:

navigationOptions = {
 headerLeft:()=>{return null},
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.