在反应导航中禁用后退按钮
Disable back button in react navigation
我正在使用反应本机导航 (react-navigation) StackNavigator。
它从登录页面开始,贯穿应用程序的整个生命周期。我不想有返回选项,返回到登录屏幕。有谁知道如何在登录屏幕后将其隐藏在屏幕上?
顺便说一句,我还通过使用将其隐藏在登录屏幕中:
const MainStack = StackNavigator({
Login: {
screen: Login,
navigationOptions: {
title: "Login",
header: {
visible: false,
},
},
},
// ... other screens here
})
我自己找到的 ;)
添加:
left: null,
禁用默认后退按钮。
const MainStack = StackNavigator({
Login: {
screen: Login,
navigationOptions: {
title: "Login",
header: {
visible: false,
},
},
},
FirstPage: {
screen: FirstPage,
navigationOptions: {
title: "FirstPage",
header: {
left: null,
}
},
},
您可以使用 left:null
隐藏后退按钮,但对于 android 设备,当用户按下后退按钮时它仍然能够返回。您需要重置导航状态并使用 left:null
隐藏按钮
这里是重置导航状态的文档:
https://reactnavigation.org/docs/navigation-actions#reset
此解决方案适用于 react-navigator 1.0.0-beta.7
,但 left:null
不再适用于最新版本。
1) 要使后退按钮在 react-navigation v2 或更新版本中消失:
v2-v4:
navigationOptions: {
title: 'MyScreen',
headerLeft: null
}
v5 或更高版本:
{
navigationOptions: {
title: 'MyScreen',
headerLeft: ()=> null,
// `headerLeft: undefined` should work too
// `headerLeft: null` should work but could trigger a TS error
}
2) 如果要清理导航堆栈:
假设您在要从中导航的屏幕上:
如果您使用的是 react-navigation v5 或更高版本,您可以使用 navigation.reset
或 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' }],
});
此处提供来源和更多信息: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 按下硬件后退按钮时关闭。
其他来源:感谢在下方添加评论并帮助将此答案更新为 v5 的用户。
反应导航版本 >= 1.0.0-beta.9
navigationOptions: {
headerLeft: null
}
我们可以通过将 headerLeft 设置为 null 来修复它
static navigationOptions =({navigation}) => {
return {
title: 'Rechercher une ville',
headerLeft: null,
}
}
我们需要将 gesturesEnabled
设置为 false,同时将 headerLeft
设置为 null
。因为我们也可以通过滑动屏幕来返回。
navigationOptions: {
title: 'Title',
headerLeft: null,
gestureEnabled: false,
}
在最新版本 (v2) 中有效 headerLeft:null
。您可以在控制器的 navigationOptions
中添加如下所示
static navigationOptions = {
headerLeft: null,
};
您是否考虑过使用 this.props.navigation.replace( "HomeScreen" )
而不是 this.props.navigation.navigate( "HomeScreen" )
。
这样你就不会向堆栈中添加任何东西。因此,如果在 Android 中按下后退按钮或在 IOS 中向右滑动屏幕,HomeScreen 将不会挥动任何要返回的内容。
更多信息查看Documentation。
当然,您可以通过在 navigationOptions
中设置 headerLeft: null
来隐藏后退按钮
对于最新版本的 React Navigation,即使您在某些情况下使用 null,它仍可能显示 "back" 已写入!
在您的 main app.js 的屏幕名称下进行此操作,或者直接转到您的 class 文件 并添加:-
static navigationOptions = {
headerTitle:'Disable back Options',
headerTitleStyle: {color:'white'},
headerStyle: {backgroundColor:'black'},
headerTintColor: 'red',
headerForceInset: {vertical: 'never'},
headerLeft: " "
}
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');
使用 React Native 的 BackHandler 对我有用。只需将这一行包含在您的 ComponentWillMount 中:
BackHandler.addEventListener('hardwareBackPress', function() {return true})
它将禁用 android 设备上的后退按钮。
我认为添加 headerLeft : null
很简单,我使用的是 react-native cli,所以这就是示例:
static navigationOptions = {
headerLeft : null
};
对于 react-navigation 版本 4.x
navigationOptions: () => ({
title: 'Configuration',
headerBackTitle: null,
headerLayoutPreset:'center',
headerLeft: null
})
处理这种情况的最佳选择是使用 React navigation 提供的 SwitchNavigator。 SwitchNavigator 的目的是一次只显示一个屏幕。默认情况下,它不处理返回操作,并且在您切换离开时将路由重置为默认状态。这正是身份验证流程中所需的行为。
这是一个典型的实现方式。
- 创建 2 个堆栈导航器:一个用于身份验证(登录、注册、忘记密码等),另一个用于主 APP
- 创建一个屏幕,您将在其中检查要显示的切换导航器的哪条路线(我通常通过检查令牌是否存储在异步存储中来在初始屏幕中检查此)
以上语句的代码实现
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>
);
}
}
Once you change routes in SwitchNavigator it removes the older route automatically and hence if you press the back button it will not take you to the auth/login screens anymore
简单做
headerLeft: null
在您阅读此答案时可能已弃用。
你应该使用以下
navigationOptions = {
headerTitle : "Title",
headerLeft : () => {},
}
headerLeft: null
这在最新的 React Native 版本中不起作用
应该是:
navigationOptions = {
headerLeft:()=>{},
}
对于打字稿:
navigationOptions = {
headerLeft:()=>{return null},
}
对于带有 Typescript 的最新版本 React Navigation 5:
<Stack.Screen
name={Routes.Consultations}
component={Consultations}
options={{headerLeft: () => null}}
/>
ReactNavigation v 5.0 - 堆栈选项:
options={{
headerLeft: () => {
return <></>;
}
}}
在 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。
从 React Navigation v5.7 开始,文档中有一个新的官方解决方案:
https://reactnavigation.org/docs/preventing-going-back
使用 beforeRemove
作为导航侦听器以防止来自 Android 后退按钮、header 后退按钮和自定义后退操作的后退行为。
虽然提供了很好的答案,但我认为这很简单
useEffect(() => {
props.navigation.addListener("beforeRemove", (e) => {
e.preventDefault();
});
}, [props.navigation]);
我正在使用 v6,它适合我:
<Stack.Screen
name="ApparelsHome"
component={ApparelsHome}
options={{
headerLeft: () => <></>,
}}
/>
如果你的反应导航v6.x
options={{
title: "Detail Pembayaran",
headerTitleStyle:{
fontWeight:'bold',
},
headerBackVisible:false
}}
您也可以headerLeft:()=>false
去掉后退按钮
<Stack.Screen name="ImageScreen" component={ShowImage} options={{title:"SMAART", headerLeft:()=>false}} />
对于 react-navigation V6.0
<Stack.Screen
name={'Dashboard'}
component={Dashboard}
options={{
gestureEnabled: false,
headerShown: true,
headerLeft: () => <></>,
}}>
</Stack.Screen>
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>
)}
我正在使用反应本机导航 (react-navigation) StackNavigator。 它从登录页面开始,贯穿应用程序的整个生命周期。我不想有返回选项,返回到登录屏幕。有谁知道如何在登录屏幕后将其隐藏在屏幕上? 顺便说一句,我还通过使用将其隐藏在登录屏幕中:
const MainStack = StackNavigator({
Login: {
screen: Login,
navigationOptions: {
title: "Login",
header: {
visible: false,
},
},
},
// ... other screens here
})
我自己找到的 ;) 添加:
left: null,
禁用默认后退按钮。
const MainStack = StackNavigator({
Login: {
screen: Login,
navigationOptions: {
title: "Login",
header: {
visible: false,
},
},
},
FirstPage: {
screen: FirstPage,
navigationOptions: {
title: "FirstPage",
header: {
left: null,
}
},
},
您可以使用 left:null
隐藏后退按钮,但对于 android 设备,当用户按下后退按钮时它仍然能够返回。您需要重置导航状态并使用 left:null
这里是重置导航状态的文档:
https://reactnavigation.org/docs/navigation-actions#reset
此解决方案适用于 react-navigator 1.0.0-beta.7
,但 left:null
不再适用于最新版本。
1) 要使后退按钮在 react-navigation v2 或更新版本中消失:
v2-v4:
navigationOptions: {
title: 'MyScreen',
headerLeft: null
}
v5 或更高版本:
{
navigationOptions: {
title: 'MyScreen',
headerLeft: ()=> null,
// `headerLeft: undefined` should work too
// `headerLeft: null` should work but could trigger a TS error
}
2) 如果要清理导航堆栈:
假设您在要从中导航的屏幕上:
如果您使用的是 react-navigation v5 或更高版本,您可以使用 navigation.reset
或 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' }],
});
此处提供来源和更多信息: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 按下硬件后退按钮时关闭。
其他来源:感谢在下方添加评论并帮助将此答案更新为 v5 的用户。
反应导航版本 >= 1.0.0-beta.9
navigationOptions: {
headerLeft: null
}
我们可以通过将 headerLeft 设置为 null 来修复它
static navigationOptions =({navigation}) => {
return {
title: 'Rechercher une ville',
headerLeft: null,
}
}
我们需要将 gesturesEnabled
设置为 false,同时将 headerLeft
设置为 null
。因为我们也可以通过滑动屏幕来返回。
navigationOptions: {
title: 'Title',
headerLeft: null,
gestureEnabled: false,
}
在最新版本 (v2) 中有效 headerLeft:null
。您可以在控制器的 navigationOptions
中添加如下所示
static navigationOptions = {
headerLeft: null,
};
您是否考虑过使用 this.props.navigation.replace( "HomeScreen" )
而不是 this.props.navigation.navigate( "HomeScreen" )
。
这样你就不会向堆栈中添加任何东西。因此,如果在 Android 中按下后退按钮或在 IOS 中向右滑动屏幕,HomeScreen 将不会挥动任何要返回的内容。
更多信息查看Documentation。
当然,您可以通过在 navigationOptions
headerLeft: null
来隐藏后退按钮
对于最新版本的 React Navigation,即使您在某些情况下使用 null,它仍可能显示 "back" 已写入!
在您的 main app.js 的屏幕名称下进行此操作,或者直接转到您的 class 文件 并添加:-
static navigationOptions = {
headerTitle:'Disable back Options',
headerTitleStyle: {color:'white'},
headerStyle: {backgroundColor:'black'},
headerTintColor: 'red',
headerForceInset: {vertical: 'never'},
headerLeft: " "
}
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');
使用 React Native 的 BackHandler 对我有用。只需将这一行包含在您的 ComponentWillMount 中:
BackHandler.addEventListener('hardwareBackPress', function() {return true})
它将禁用 android 设备上的后退按钮。
我认为添加 headerLeft : null
很简单,我使用的是 react-native cli,所以这就是示例:
static navigationOptions = {
headerLeft : null
};
对于 react-navigation 版本 4.x
navigationOptions: () => ({
title: 'Configuration',
headerBackTitle: null,
headerLayoutPreset:'center',
headerLeft: null
})
处理这种情况的最佳选择是使用 React navigation 提供的 SwitchNavigator。 SwitchNavigator 的目的是一次只显示一个屏幕。默认情况下,它不处理返回操作,并且在您切换离开时将路由重置为默认状态。这正是身份验证流程中所需的行为。
这是一个典型的实现方式。
- 创建 2 个堆栈导航器:一个用于身份验证(登录、注册、忘记密码等),另一个用于主 APP
- 创建一个屏幕,您将在其中检查要显示的切换导航器的哪条路线(我通常通过检查令牌是否存储在异步存储中来在初始屏幕中检查此)
以上语句的代码实现
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>
);
}
}
Once you change routes in SwitchNavigator it removes the older route automatically and hence if you press the back button it will not take you to the auth/login screens anymore
简单做
headerLeft: null
在您阅读此答案时可能已弃用。 你应该使用以下
navigationOptions = {
headerTitle : "Title",
headerLeft : () => {},
}
headerLeft: null
这在最新的 React Native 版本中不起作用
应该是:
navigationOptions = {
headerLeft:()=>{},
}
对于打字稿:
navigationOptions = {
headerLeft:()=>{return null},
}
对于带有 Typescript 的最新版本 React Navigation 5:
<Stack.Screen
name={Routes.Consultations}
component={Consultations}
options={{headerLeft: () => null}}
/>
ReactNavigation v 5.0 - 堆栈选项:
options={{
headerLeft: () => {
return <></>;
}
}}
在 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。
从 React Navigation v5.7 开始,文档中有一个新的官方解决方案:
https://reactnavigation.org/docs/preventing-going-back
使用 beforeRemove
作为导航侦听器以防止来自 Android 后退按钮、header 后退按钮和自定义后退操作的后退行为。
虽然提供了很好的答案,但我认为这很简单
useEffect(() => {
props.navigation.addListener("beforeRemove", (e) => {
e.preventDefault();
});
}, [props.navigation]);
我正在使用 v6,它适合我:
<Stack.Screen
name="ApparelsHome"
component={ApparelsHome}
options={{
headerLeft: () => <></>,
}}
/>
如果你的反应导航v6.x
options={{
title: "Detail Pembayaran",
headerTitleStyle:{
fontWeight:'bold',
},
headerBackVisible:false
}}
您也可以headerLeft:()=>false
去掉后退按钮
<Stack.Screen name="ImageScreen" component={ShowImage} options={{title:"SMAART", headerLeft:()=>false}} />
对于 react-navigation V6.0
<Stack.Screen
name={'Dashboard'}
component={Dashboard}
options={{
gestureEnabled: false,
headerShown: true,
headerLeft: () => <></>,
}}>
</Stack.Screen>
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>
)}