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

时间:2017-03-16 10:39:03

标签: reactjs react-native navigation react-navigation

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

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

21 个答案:

答案 0 :(得分:115)

对于反应导航版本v1> = 1.0.0-beta.9 ,要使后退按钮消失:

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

如果你想清理导航堆栈,你也可以这样做(假设你在你要导航的屏幕上):

import { NavigationActions } from 'react-navigation';

并使用一个函数导航到目标路线,该路线将禁用所有后退功能:

resetNavigation(targetRoute) {
  const resetAction = NavigationActions.reset({
    index: 0,
    actions: [
      NavigationActions.navigate({ routeName: targetRoute }),
    ],
  });
  this.props.navigation.dispatch(resetAction);
}

然后打电话 this.resetNavigation('myRouteWithDisabledBackFunctionality')  当您想要导航到目标路线时

对于react-navigation v2版本,您需要使用StackAction.reset(...)代替NavigationActions.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);

更多信息: https://reactnavigation.org/docs/en/stack-actions.html

答案 1 :(得分:16)

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

隐藏按钮

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

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

答案 2 :(得分:10)

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

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

更多信息,请检查Documentation。 当然,您可以通过在headerLeft: null

中设置navigationOptions隐藏后退按钮

答案 3 :(得分:7)

我们需要将gesturesEnabledheaderLeft设置为null。因为我们也可以通过滑动屏幕来导航回来。

navigationOptions:  {
        title: 'Title',
        headerLeft: null,
        gesturesEnabled: false,
}

答案 4 :(得分:3)

react-navigation版本&gt; = 1.0.0-beta.9

navigationOptions:  {
headerLeft: null}

答案 5 :(得分:3)

自己发现;) 中加入:

  left: null,

禁用默认后退按钮。

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

答案 6 :(得分:2)

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

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

它将禁用android设备上的后退按钮。

答案 7 :(得分:2)

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

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

答案 8 :(得分:1)

简单地做

headerLeft: null
在您阅读此答案时,

可能已被弃用。 您应该使用以下

   navigationOptions = {
        headerTitle : "Title",
        headerLeft : () => {},
    }

答案 9 :(得分:1)

ReactNavigation v 5.0-堆栈选项:

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

答案 10 :(得分: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: " "
      }

答案 11 :(得分:0)

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

答案 12 :(得分:0)

在最新版本(v2)中,headerLeft:null有效。您可以在下面添加控制器的navigationOptions

static navigationOptions = {
    headerLeft: null,
  };

答案 13 :(得分:0)

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

static navigationOptions = {
        headerLeft : null
    };

答案 14 :(得分:0)

对于反应导航版本4.x

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

答案 15 :(得分:0)

处理这种情况的最佳选择是使用React navigation提供的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中更改了路由,它将自动删除较旧的路由,因此,如果您按下“后退”按钮,它将不再带您进入“身份验证/登录”屏幕

答案 16 :(得分:0)

headerLeft: null

这不适用于最新的React Native版本

应该是:

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

对于打字稿:

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

答案 17 :(得分:0)

我们可以通过将headerLeft设置为null来修复它

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

答案 18 :(得分:0)

在 react-navigation 5.x 版本中,你可以这样做:

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

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

您可以阅读更多here

答案 19 :(得分:0)

从 React Navigation v5.7 开始,文档中有一个新的官方解决方案:

https://reactnavigation.org/docs/preventing-going-back

使用 beforeRemove 作为导航侦听器,以防止来自 Android 后退按钮、标题后退按钮和自定义后退动作的后退行为。

答案 20 :(得分:0)

虽然提供了很好的答案,但我认为这很简单

    useEffect(() => {
    props.navigation.addListener("beforeRemove", (e) => {
      e.preventDefault();
    });
  }, [props.navigation]);