使用expo-router时如何阻止默认返回导航?
在 Expo Router 中阻止默认返回导航(含滑动返回)
核心问题分析
你遇到的navigation为undefined,是因为 Expo Router 的页面组件不会默认将navigation作为 props 传递,必须通过useNavigation钩子获取;同时你在_layout.tsx中错误嵌套了Stack.Screen,应该使用自定义栈导航器的CustomStack.Screen来关联导航上下文。
修正后的完整代码
1. CustomStack.tsx(无需修改,确认类型正确)
import { createStackNavigator, StackNavigationOptions } from "@react-navigation/stack"; import { withLayoutContext } from "expo-router"; const { Navigator } = createStackNavigator(); export const CustomStack = withLayoutContext<StackNavigationOptions, typeof Navigator>(Navigator);
2. _layout.tsx(替换为CustomStack.Screen)
import { CustomStack } from "./CustomStack"; // 定义路由参数类型,用于TypeScript类型提示 export type RootStackParamList = { Home: undefined; About: undefined; // 其他页面的参数定义,无参数则设为undefined }; export default function RootLayout() { return ( <CustomStack> <CustomStack.Screen name="Home" /> <CustomStack.Screen name="About" /> {/* 其他页面路由 */} </CustomStack> ); }
3. About.tsx(使用useNavigation获取导航实例,监听beforeRemove)
import { useNavigation, StackNavigationProp } from "@react-navigation/native"; import { useEffect, Alert } from 'react'; import type { RootStackParamList } from '../_layout'; // 约束当前页面的navigation类型 type AboutScreenNavigationProp = StackNavigationProp<RootStackParamList, 'About'>; export default function About() { const navigation = useNavigation<AboutScreenNavigationProp>(); useEffect(() => { // 监听beforeRemove事件,拦截返回操作 const unsubscribe = navigation.addListener('beforeRemove', (e) => { e.preventDefault(); Alert.alert( 'Changes might be lost', 'Really want to go back?', [ { text: "Cancel", style: 'cancel', onPress: () => {} }, { text: "Yes", style: 'destructive', onPress: () => navigation.dispatch(e.data.action), }, ] ); }); // 组件卸载时移除监听器,避免内存泄漏 return unsubscribe; }, [navigation]); return ( {/* 你的页面内容 */} ); }
额外选项:直接禁用滑动返回手势
如果不需要弹窗确认,只想直接禁用Google Pixel的左滑返回,可以在_layout.tsx的页面配置中添加gestureEnabled: false:
<CustomStack.Screen name="About" options={{ gestureEnabled: false }} />
关键说明
- Expo Router 不支持通过组件props传递
navigation,必须使用useNavigation钩子获取导航实例。 - 自定义栈导航器的
Screen组件必须从CustomStack中获取,才能保证页面能正确关联导航上下文。 - 监听事件后一定要返回卸载函数,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Thomas Pötz
相关产品推荐
相关产品推荐

