【问题标题】:Disable back button in react navigation在反应导航中禁用后退按钮
【发布时间】:2017-08-07 11:40:01
【问题描述】:

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

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

【问题讨论】:

  • 在 versin 4 和更早版本中试试这个:headerLeft:()=>null

标签: reactjs react-native navigation react-navigation


【解决方案1】:

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

v2-v4:

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

v5

{     
    navigationOptions:  {
    title: 'MyScreen',
    headerLeft: ()=> null, // Note: using just `null` instead of a function should also work but could trigger a TS error
}

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

假设您在要从中导航的屏幕上:

如果您使用 react-navigation 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

对于旧版本的 react-navigation:

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 硬件后退按钮时关闭。

其他来源:感谢在下面添加 cmets 并帮助保持此答案针对 v5 更新的用户。

【讨论】:

  • 这将删除返回按钮,但在 android 中我们仍然可以使用设备返回按钮进行导航。有没有办法也禁用它?
  • 你是国王
  • 当你在 2018 年使用“StackAction.reset(...)”而不是“NavigationActions.reset(...)”时,请参阅reactnavigation.org/docs/en/stack-actions.html
  • 使用“index:1”时“无法读取未定义的键”。所以为了修复这个错误,我使用“index:0”。我觉得有道理
  • 似乎 API 再次得到改进,至少在 v5 中,现在有一种更短的方式来执行该重置操作:reactnavigation.org/docs/navigation-prop#reset
【解决方案2】:

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

这样你就不会向堆栈添加任何东西。因此,如果在 Android 中按下返回按钮或在 IOS 中向右滑动屏幕,HomeScreen 将不会挥手返回任何内容。

更多信息请查看Documentation。 当然,您可以通过在navigationOptions 中设置headerLeft: null 来隐藏后退按钮

【讨论】:

  • 你不能使用replace传递参数。
  • 你应该做的警告错误修复`()=>null`
  • tq 它工作...参数也可以传递
【解决方案3】:

我们需要将 gesturesEnabled 设置为 false 以及将 headerLeft 设置为 null。因为我们也可以通过滑动屏幕来导航。

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

【讨论】:

  • gesturesEnabled 甚至不作为属性存在!
  • 不错!手势启用正是我想要的。非常感谢!
【解决方案4】:

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

这里是重置导航状态的文档:
https://reactnavigation.org/docs/navigation-actions#reset

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

【讨论】:

  • 在 iOS 上,您仍然可以从屏幕边缘滑动以弹回。绝对需要重置导航状态。
【解决方案5】:

使用来自 react native 的 BackHandler 对我有用。只需在您的 ComponentWillMount 中包含这一行:

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

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

【讨论】:

  • 这仅适用于 Android。
【解决方案6】:

如果你的反应导航 v6.x

options={{
   title: "Detail Pembayaran",
   headerTitleStyle:{
      fontWeight:'bold',
   },
   headerBackVisible:false
}}

参考:React document

【讨论】:

    【解决方案7】:

    我自己找到的;) 添加:

      left: null,
    

    禁用默认的后退按钮。

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

    【讨论】:

      【解决方案8】:

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

      navigationOptions:  {
         headerLeft: null
      }
      

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

          【解决方案10】:

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

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

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

          【讨论】:

          • 是的 - 这对于防止由于未保存的更改而导致的转换非常有用。但是,如果您的目标是防止返回登录或入职屏幕,那么您可以只使用 navigation.replace 而不是 navigation.navigate
          【解决方案11】:

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

          【讨论】:

            【解决方案12】:

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

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

            【讨论】:

              【解决方案13】:

              只是做

              headerLeft: null
              

              在您阅读此答案时可能已弃用。 您应该使用以下

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

              【讨论】:

                【解决方案14】:

                我使用的是 v6,它适用于我:

                 <Stack.Screen
                    name="ApparelsHome"
                    component={ApparelsHome}
                    options={{
                      headerLeft: () => <></>,
                    }}
                />
                

                【讨论】:

                  【解决方案15】:

                  适用于 react-navigation V6.0

                  <Stack.Screen
                            name={'Dashboard'}
                            component={Dashboard}
                            options={{
                              gestureEnabled: false,
                              headerShown: true,
                              headerLeft: () => <></>,
                            }}>
                  </Stack.Screen>
                  

                  【讨论】:

                    【解决方案16】:

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

                    【讨论】:

                      【解决方案17】:

                      ReactNavigation v 5.0 - 堆栈选项:

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

                      【讨论】:

                      • 请始终在回答中描述您在做什么。它应该被更新或删除。在提供更多答案之前阅读How to answer ^^
                      【解决方案18】:

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

                      static navigationOptions = {
                          headerLeft : null
                      };
                      

                      【讨论】:

                        【解决方案19】:

                        对于最新版本的 React Navigation,即使您在某些情况下使用 null,它仍可能显示“返回”写入!

                        在您的 ma​​in app.js 中使用您的屏幕名称,或者只需转到您的 class 文件 并添加:-

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

                        【讨论】:

                          【解决方案20】:

                          在最新版本 (v2) 中工作 headerLeft:null。您可以添加控制器的navigationOptions,如下所示

                          static navigationOptions = {
                              headerLeft: null,
                          };
                          

                          【讨论】:

                            【解决方案21】:

                            对于 react-navigation 4.x 版

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

                            【讨论】:

                              【解决方案22】:
                              headerLeft: null
                              

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

                              应该是:

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

                              对于打字稿:

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

                              【讨论】:

                                【解决方案23】:

                                在 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

                                【讨论】:

                                  【解决方案24】:

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

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

                                  【讨论】:

                                    【解决方案25】:

                                    你也可以通过headerLeft:()=&gt;false 去掉后退按钮

                                    <Stack.Screen name="ImageScreen" component={ShowImage} options={{title:"SMAART", headerLeft:()=>false}} />
                                    

                                    【讨论】:

                                    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
                                    【解决方案26】:
                                    import React,{useEffect,useState,useRef} from 'react';
                                    import { BackHandler,View } from 'react-native';
                                    
                                    export default function App() {
                                    
                                      useEffect(() => {
                                        const backHandler = BackHandler.addEventListener('hardwareBackPress', () => true)
                                        return () => backHandler.remove()
                                      }, [])
                                    
                                    return(
                                    <View>
                                    
                                    </View>
                                    )}
                                    

                                    【讨论】:

                                      猜你喜欢
                                      • 1970-01-01
                                      • 2014-01-16
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2020-10-15
                                      • 1970-01-01
                                      • 2015-11-07
                                      • 1970-01-01
                                      • 2015-05-02
                                      相关资源
                                      最近更新 更多