You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 11:35:33