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

使用Expo Router数组语法配置共享路由时出现路由不匹配问题

问题

使用npx expo init创建基础Expo TypeScript项目,已安装expo-router和expo-dev-client,Web端运行。尝试使用共享路由的数组语法访问app/目录下的路由时,出现路由不匹配错误:

Unmatched Route

Page could not be found. Go back.
[http://localhost:8081/events/(manage)/1234]

(http://localhost:8081/events/1234)

当前目录结构:

app/
  index.tsx
  _layout.tsx

  events/
    (manage, preview)/
      [eventID].tsx
       _layout.tsx

访问/events/1234可正常加载,但无法区分manage和preview子视图;成功访问时,(manage, preview)/_layout.tsx中打印的segment为events/(manage,preview)。

最小复现代码:

app/index.tsx

import { Link, useRouter } from "expo-router";
import { Button } from "react-native";

export default function Page() {
  const router = useRouter()
  return <>
    <Link href="/events/(manage)/1234">
      I don't work
    </Link>
    <Button title="I don't work" onPress={() => router.push("/events/(manage)/1234")} />

    <Link href="/events/1234">
      I work but am confused...
    </Link>
    <Button title="I work but am confused..." onPress={() => router.push("/events/1234")} />
  </>
}

events/(manage,preview)/_layout.tsx

import { Slot } from "expo-router";

export default function DynamicLayout({ segment }) {
  console.log(segment);

  return <Slot />;
}

events/(manage,preview)/[eventID].tsx

import { useLocalSearchParams, usePathname } from "expo-router";
import { Text } from "react-native";

const Page = () => {
  const pathname = usePathname();
  const localSearchParams = useLocalSearchParams();

  return (
    <Text>
      {pathname} : {localSearchParams.eventID}
    </Text>
  );
};

解决方案

核心问题

Expo Router的(a,b)共享路由语法是用于定义多个路由路径共享同一组件/布局,并非允许通过/(manage)/的格式直接访问。你尝试的URL格式不符合框架的路由解析规则,因此出现不匹配错误。

方案1:拆分显式分组路由(推荐)

将共享路由拆分为两个独立的分组,同时复用核心组件:
调整目录结构:

app/
  index.tsx
  _layout.tsx

  events/
    (manage)/
      [eventID].tsx
      _layout.tsx
    (preview)/
      [eventID].tsx
      _layout.tsx

然后在两个分组的[eventID].tsx中导入同一个共享组件:

// events/(manage)/[eventID].tsx
import EventPage from '../../components/EventPage';
export default EventPage;

// events/(preview)/[eventID].tsx
import EventPage from '../../components/EventPage';
export default EventPage;

这样访问/events/(manage)/1234和/events/(preview)/1234即可正常区分视图,同时复用业务逻辑。

方案2:使用查询参数区分视图

保持现有目录结构,通过查询参数传递视图类型:
修改跳转逻辑:

// app/index.tsx
<Link href="/events/1234?view=manage">Manage Event</Link>
<Button title="Manage Event" onPress={() => router.push("/events/1234?view=manage")} />

<Link href="/events/1234?view=preview">Preview Event</Link>
<Button title="Preview Event" onPress={() => router.push("/events/1234?view=preview")} />

在[eventID].tsx中获取参数并渲染对应视图:

import { useLocalSearchParams, usePathname } from "expo-router";
import { Text } from "react-native";

const Page = () => {
  const pathname = usePathname();
  const { eventID, view } = useLocalSearchParams();

  return (
    <Text>
      {pathname} : {eventID} | View: {view || 'default'}
    </Text>
  );
};

方案3:利用布局逻辑动态区分

如果不需要在URL中显式区分视图,可以在(manage,preview)/_layout.tsx中通过路由上下文或状态判断渲染内容,但这种方式适合不需要URL区分的场景。


内容的提问来源于stack exchange,提问作者Francis Leigh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:57:10