先看看示例
作者提供的示例,实际效果取决于你的输入和使用工具。
输入
已有 Expo 项目保留根布局与 / 路由。新增 /orders 列表和 /orders/[id] 详情;演示只使用本地 demo-42 订单,未知 id 显示未找到;接入真实接口时另核验登录与对象权限。
输出
编辑示例 · 未运行
// src/app/orders/_layout.tsx
import { Stack } from "expo-router/stack";
export default function OrdersLayout() {
return (
<Stack>
<Stack.Screen name="index" options={{ title: "订单" }} />
<Stack.Screen name="[id]" options={{ title: "订单详情" }} />
</Stack>
);
}// src/app/orders/index.tsx
import { Link } from "expo-router";
import { Text, View } from "react-native";
export default function OrdersScreen() {
return (
<View>
<Text>订单列表</Text>
<Link href={{ pathname: "/orders/[id]", params: { id: "demo-42" } }}>
查看示例订单
</Link>
</View>
);
}// src/app/orders/[id].tsx
import { useEffect, useState } from "react";
import { useLocalSearchParams } from "expo-router";
import { ActivityIndicator, Text, View } from "react-native";
export default function OrderDetailScreen() {
const { id } = useLocalSearchParams<{ id?: string | string[] }>();
const orderId = typeof id === "string" ? id : null;
const [loading, setLoading] = useState(true);
const [order, setOrder] = useState<{ id: string; title: string } | null>(null);
useEffect(() => {
let active = true;
setLoading(true);
// 本地演示数据;真实接口还需错误处理和服务端权限检查。
const record = orderId === "demo-42"
? { id: orderId, title: "示例订单" }
: null;
Promise.resolve(record).then(value => {
if (active) {
setOrder(value);
setLoading(false);
}
});
return () => { active = false; };
}, [orderId]);
if (loading) return <ActivityIndicator accessibilityLabel="正在加载订单" />;
if (!order) return <Text>未找到订单</Text>;
return <View><Text>{order.title}</Text><Text>编号:{order.id}</Text></View>;
}三个代码块分别保存为注释标明的文件,加入现有根布局。Hook 位于详情组件内部,所用组件均显式导入;这是未运行的本地演示,真实数据请求还需独立处理加载失败和无权访问。
方法说明
把页面路径、参数、标签页和模态入口组织成清晰的文件路由,处理平台差异与返回行为。
具体任务
建立订单列表到详情的路由:把页面路径、参数、标签页和模态入口组织成清晰的文件路由,处理平台差异与返回行为。
组织弹窗和标签导航:按页面关系配置 Stack、路由组和 Modal,检查深链接进入与关闭后的去向。
必需材料
Expo 项目与 Router 版本
页面清单、参数与返回规则
可选材料
深链接示例
原生平台目标
使用门槛
了解 app 或 src/app 的文件路由约定,并可运行目标平台。
这个 Skill 额外提供的方法
用路由文件、布局和明确返回路径组织页面,避免参数和导航状态散落在组件里。
编辑示例(未运行)
建立订单列表到详情的路由
任务:请根据下面的示例材料完成建立订单列表到详情的路由,把判断依据和待确认事项写清楚。
输入:
已有 Expo 项目保留根布局与 / 路由。新增 /orders 列表和 /orders/[id] 详情;演示只使用本地 demo-42 订单,未知 id 显示未找到;接入真实接口时另核验登录与对象权限。
结果片段:
```tsx
// src/app/orders/_layout.tsx
import { Stack } from "expo-router/stack";
export default function OrdersLayout() {
return (
<Stack>
<Stack.Screen name="index" options={{ title: "订单" }} />
<Stack.Screen name="[id]" options={{ title: "订单详情" }} />
</Stack>
);
}
```
```tsx
// src/app/orders/index.tsx
import { Link } from "expo-router";
import { Text, View } from "react-native";
export default function OrdersScreen() {
return (
<View>
<Text>订单列表</Text>
<Link href={{ pathname: "/orders/[id]", params: { id: "demo-42" } }}>
查看示例订单
</Link>
</View>
);
}
```
```tsx
// src/app/orders/[id].tsx
import { useEffect, useState } from "react";
import { useLocalSearchParams } from "expo-router";
import { ActivityIndicator, Text, View } from "react-native";
export default function OrderDetailScreen() {
const { id } = useLocalSearchParams<{ id?: string | string[] }>();
const orderId = typeof id === "string" ? id : null;
const [loading, setLoading] = useState(true);
const [order, setOrder] = useState<{ id: string; title: string } | null>(null);
useEffect(() => {
let active = true;
setLoading(true);
// 本地演示数据;真实接口还需错误处理和服务端权限检查。
const record = orderId === "demo-42"
? { id: orderId, title: "示例订单" }
: null;
Promise.resolve(record).then(value => {
if (active) {
setOrder(value);
setLoading(false);
}
});
return () => { active = false; };
}, [orderId]);
if (loading) return <ActivityIndicator accessibilityLabel="正在加载订单" />;
if (!order) return <Text>未找到订单</Text>;
return <View><Text>{order.title}</Text><Text>编号:{order.id}</Text></View>;
}
```
三个代码块分别保存为注释标明的文件,加入现有根布局。Hook 位于详情组件内部,所用组件均显式导入;这是未运行的本地演示,真实数据请求还需独立处理加载失败和无权访问。
用路由文件、布局和明确返回路径组织页面,避免参数和导航状态散落在组件里。 该片段是编辑示例,用于说明交付形态,未运行上游技能。
首次任务
请使用「用 Expo Router 组织应用页面与导航」完成「建立订单列表到详情的路由」。
任务要求:用路由文件、布局和明确返回路径组织页面,避免参数和导航状态散落在组件里。
我的必需材料:
- Expo 项目与 Router 版本:[请填写或粘贴]
- 页面清单、参数与返回规则:[请填写或粘贴]
请基于上述实际材料输出:路由结构、导航配置与返回路径验证。缺少依据的地方单列为待确认,不编造事实;未执行的操作或测试明确标为未执行。
验收要求:
1. 列表进入和返回保留合理上下文。
2. 直接打开详情链接可处理参数和缺失数据。
3. 目标平台导航行为与版本支持一致。
验收方法
列表进入和返回保留合理上下文
直接打开详情链接可处理参数和缺失数据
目标平台导航行为与版本支持一致
依赖与准备
需要兼容版本的 Expo、expo-router 和相应平台运行环境;保留技能引用的路由结构与导航参考,原生功能按 SDK 支持核对。
使用边界
原生 Tabs、菜单与 Sheet 能力受 Expo SDK 和平台版本影响。
导航代码不会代替服务端授权,详情页仍需检查数据访问权限。
排错
返回跳到意外页面:检查路由组和初始路由设置,分别验证站内进入与深链接进入。
参数有时是数组或空值:校验路由参数后再加载,不直接拼接请求。
固定来源
https://github.com/expo/skills/blob/c0dadf355d4caa4e1720de372f0f8766df1a8978/plugins/expo/skills/expo-router/SKILL.md