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

Expo Router动态路由返回异常:返回直接跳首页而非上一级动态页

问题

从 /home 导航至 /listing/1,再从该页面跳转至 /listing/2,点击返回按钮或滑动返回时,并未回到 /listing/1,而是直接返回 /home。是否因为 Expo Router 未将动态路由添加至历史记录而是进行了替换?该如何修复?


相关信息

文件夹结构

[对应截图链接]

主布局代码

<Stack>
  <Stack.Screen
    name="index"
    options={{
      headerShown: false,
    }}
  />
  <Stack.Screen
    name="+not-found"
    options={{
      headerShown: false,
    }}
  />
  <Stack.Screen name="(auth)" options={{ headerShown: false }} />
  <Stack.Screen name="(main)" options={{ headerShown: false }} />
  <Stack.Screen name="listing/[id]" options={{ headerShown: false }} />
  <Stack.Screen name="chef/[id]" options={{ headerShown: false }} />
  <Stack.Screen name="category/[id]" options={{ headerShown: false }} />
</Stack>

返回按钮代码

import React from "react";
import { TouchableOpacity } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import { useRouter, useNavigation } from "expo-router";

interface BackButtonProps {
  size?: number;
  color?: string;
  className?: string;
}

const BackButton: React.FC<BackButtonProps> = ({ size = 24, color = "gray", className = "" }) => {
  const router = useRouter();
  const navigation = useNavigation();

  // Check if we can go back
  const canGoBack = navigation.canGoBack();

  return (
    <TouchableOpacity
      onPress={() => {
        if (canGoBack) {
          // Use router.back() if we can go back
          router.back();
        } else {
          // If we can't go back, go to the home screen
          router.replace("/");
        }
      }}
      className={`rounded-full ${className}`}>
      <Ionicons name="chevron-back" size={size} color={color} />
    </TouchableOpacity>
  );
};

export default BackButton;

依赖版本

"@react-navigation/native": "^6.0.2",
"expo-linking": "~7.0.4",
"expo-router": "~4.0.16",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-native": "0.76.6",

原因分析

是的,问题核心是从 /listing/1 跳转到 /listing/2 时使用了 router.replace() 方法而非 router.push()。replace() 会替换当前历史栈条目,而非添加新条目,导致历史栈中仅保留 /home 和 /listing/2,返回时直接回到 /home。

另外,虽然你的栈配置中已将 listing/[id] 设为独立屏幕,同模板动态路由默认应被加入历史栈,但错误的跳转方式会覆盖这一行为。


修复方案
  1. 修正跳转方法
    确保跳转时使用 router.push() 添加新历史条目:

    // 错误写法
    router.replace(`/listing/2`);
    // 正确写法
    router.push(`/listing/2`);
    
  2. 验证返回按钮逻辑
    当前返回按钮使用 navigation.canGoBack() + router.back() 的逻辑是合理的,若仍有问题,可直接调用 router.back()(无需判断的场景下),但现有逻辑无需修改。

  3. 确认路由文件夹结构
    确保动态路由文件结构为 app/listing/[id].tsx(或 .jsx),若为嵌套结构(如 app/listing/[id]/index.tsx),需保证路由配置与文件结构匹配,让 Expo Router 正确识别并维护历史栈。


内容的提问来源于stack exchange,提问作者Ash Gharibyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 02:50:18