本节摘要:跳转携带什么、返回带回什么、屏幕自己的数据住在哪——本节划清「路由参数」与「全局状态」的边界,给出类型化参数的定义范式,拆解一次完整跳转的时序,并补齐自定义导航栏与转场动画的两端处理。核心纪律一句话:参数是路条不是仓库,只写本次旅程必需的通行信息。
最常见的导航事故是把参数当仓库用:列表页把整个商品对象序列化后塞进跳转参数,详情页从参数里读全部数据。短期看省了一次请求,代价立刻出现——参数膨胀让跳转变慢、对象里带函数或循环引用直接崩溃、从深层链接冷启动进来时根本没有这个「仓库」导致页面空转。正确的分工:参数只传「定位信息」(商品标识、来源、标题占位),详情数据由目标屏幕凭标识自行获取——这一下就把导航层与数据层解耦了,也是 5.3 深层链接能成立的前提:外部进来只带一个链接,照样能还原整页。
类型化参数把这条纪律固化下来。给每个屏幕声明参数形状后,跳转处写错字段名、漏传必填项,编译期就报错:
// 屏幕参数清单:全应用路由的类型户口本 type RootStackParamList = { Home: undefined; Detail: { id: string; from?: 'list' | 'favorite' }; Editor: { draftId?: string; mode: 'create' | 'edit' }; };
// 跳转处:只传定位信息,字段与类型户口本对齐 function goDetail(item, source) { navigation.navigate('Detail', { id: item.id, from: source }); } // 目标屏幕:凭标识自取数据,参数缺省有兜底 function DetailScreen({ route, navigation }) { const { id, from = 'list' } = route.params; const detail = useDetail(id); // 凭标识取数,而非读参数里的现成对象 // ... }
把「列表点进详情、编辑后带回结果」这条最经典的链路按时序拆开,导航层与数据层各干什么一目了然:
时序里有几个容易含糊的点值得点名。其一,「返回带结果」有两种实现:轻量的用「返回时附带回执」,上一屏校验回执决定刷新;有复杂的跨屏协作诉求(多屏共同编辑同一份草稿)则应该把这份共享数据提升为全局状态——导航层只负责「你回来 了」,不负责「把货搬回去」。其二,返回后的刷新要认准「参数或回执变了才刷」,无脑在每次聚焦时刷新会浪费流量并造成列表闪动。其三,转场动画进行期间参数已就位、数据未必就位——骨架屏要在动画结束前顶上,否则用户看到的是转场后的一块空白。
默认导航栏与转场是「方言区」,两端审美与物理习惯不同,精装修要按端施工。导航栏:标题居中是 iOS 惯例,Android 原生习惯偏左对齐;返回按钮的样式两端也不同。React Navigation 允许逐屏替换导航栏为自定义组件——建议的度是「结构用默认、品牌换皮肤」:安全区、返回手势、状态栏联动这些与土壤深度耦合的部分交给框架默认实现,只把标题区、按钮区换成品牌组件,整栏推倒重来的做法在 iOS 上极易弄丢边缘滑返的物理手感。转场动画:两端的系统级转场方向感不同(iOS 推入感、Android 更平移),框架的默认转场已经按端适配;确实要自定义时,优先用容器提供的转场配置项微调时长与曲线,转场是「肌肉记忆区」,越接近系统默认越不违和——这条判断与 3.4 节动画的线程判据呼应:转场动画必须走原生驱动,任何逐帧经 JS 的自定义转场都会在低端机上露怯。
返回值只是跨屏协作的一种。把常见模式按射程排开,选型时对号入座:模式一,路条参数(本节主角):父屏到子屏的一次性定向传递,射程一跳,适合「把标识带过去」。模式二,回执:子屏返回时附带回执参数,父屏校验后定向更新,射程一跳往返,适合「带着结果回来」。模式三,广播:经全局状态、事件总线或请求缓存失效通知所有相关页面,射程全应用,适合「改动影响多处」(收藏、点赞、购物车数量)。前两种走导航层,第三种走 4.3 的数据层——选错射程的症状很有辨识度:用广播做单线传递,会发现「刷新逻辑到处都是」;用回执做广播,会发现「回执链串了三层还没传完」。
还有一种特殊场景值得单列:页面没返回,数据已变化。比如详情页在后台收到推送,列表已过时,但用户还在详情页没回去。此时回执无从谈起,正确做法是列表订阅缓存失效信号,聚焦时(重新获得活跃状态)按失效标记刷新——2.3 的 AppState 在这里与导航聚焦事件配合使用。跨屏通信的完整心智模型就是这两句:通信看射程,刷新看焦点。
背景:内容管理应用的编辑页保存成功后返回列表,列表必须在顶部插入新条目,但早期实现「每次返回都全量刷新」,列表闪动明显,流量翻倍。操作:改为回执制——编辑页保存成功后返回并附带回执(新条目标识与操作类型);列表屏只在校验回执有效时做定向更新:新建则插到列表头,编辑则原位替换,删除则移除;回执缺失(用户未保存直接返回)时什么都不做。结果:返回后列表无闪动,流量回落,跨端行为一致;iOS 侧边缘滑返的中途取消场景也天然正确——没保存就没有回执,列表纹丝不动。解读:回执制的本质是把「刷新决策」从「猜测」变成「确认」,参数与回执都是小体积定位信息,与「参数是路条」的纪律同源。变式:如果编辑结果需要多处页面感知(列表、收藏夹、搜索结果都可能出现该条目),定向更新就该升级为「全局状态或请求缓存失效」方案——5.2 的回执管单线父子,广播式更新交给 4.3 的缓存层,各管各的射程。
骨架与管线都通了,最后一节打通向外的门:深层链接,让外部世界一枚链接直达你的任意房间。