跨端路由设计:如何统一 RN 与 Web 的页面模型


网罗开发 (小红书、快手、视频号同名)

大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验 。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员

👋 大家好,我是展菲!

📱 全网搜索"展菲",即可纵览我在各大平台的知识足迹。

📣 公众号"Swift社区",每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。

💬 微信端添加好友"fzhanfei",与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。

📅 最新动态:2025 年 3 月 17 日

快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!

文章目录

摘要

如果你同时做过 RN 和 Web 项目,大概率会有一种撕裂感:

  • RN 项目里,页面明明还在,却什么都不能随便跑
  • Web 项目里,页面一切都靠 mounted 和 unmounted
  • RN 强调 focus / blur
  • Web 强调 created / mounted / destroyed

最后的结果是:

同一个业务,在 RN 和 Web 里需要两套完全不同的设计方式

但问题其实不在技术栈,而在页面模型没有统一

这篇文章要做的不是"对比",而是给出一个结论:

RN 和 Web 本质上可以共享同一套页面心智模型。

一个先抛出来的结论

页面不是"是否存在"的问题,而是"当前处于什么阶段"。

一旦你用"阶段"来理解页面,RN 和 Web 的差异会迅速缩小。

先拆掉一个常见误解

误解:RN 页面不会被销毁,Web 页面会

这句话只对了一半

  • RN 页面通常常驻内存
  • Web 页面通常会被销毁

但真正重要的不是存不存在,而是:

页面当前是否应该响应用户、请求数据、触发副作用

一个统一的页面阶段模型

不管 RN 还是 Web,每一个页面其实都经历这四个阶段:

  1. 创建(Create)
  2. 挂载(Mount)
  3. 激活(Active / Focus)
  4. 休眠(Inactive / Blur)
  5. 销毁(Destroy)

差别只在于:

  • RN 默认页面不会 Destroy
  • Web 默认页面不会 Inactive

RN 是怎么强迫你面对这个模型的?

在 React Navigation 里,你几乎一定会遇到:

js 复制代码
useFocusEffect(
  React.useCallback(() => {
    fetchData();
    return () => {
      cancelRequest();
    };
  }, [])
);

这段代码背后的假设是:

  • 页面存在,但未必可见
  • 副作用必须和"聚焦状态"绑定

RN 不给你偷懒空间

Web 项目为什么一直在逃避这个问题?

因为 Web Router 默认给你的是:

js 复制代码
mounted() {
  fetchData();
}

没有 focus,也没有 blur。

于是开发者自然会把:

  • 初始化
  • 请求
  • 监听
  • 轮询

全部堆进 mounted。

keep-alive 的真正作用是什么?

从跨端视角看:

keep-alive = 给 Web 补上 "Inactive / Active" 这两个阶段

但问题是:

  • Web 项目引入了 keep-alive
  • 却没有引入阶段意识

于是就变成:

页面存在,但逻辑不知道自己该不该跑

统一 RN 与 Web 的关键:抽象"页面阶段"

我们先不谈框架,直接定义一个跨端页面阶段接口

ts 复制代码
interface PageLifecycle {
  onCreate(): void;
  onMount(): void;
  onActive(): void;
  onInactive(): void;
  onDestroy(): void;
}

这套模型在两个端上都成立。

RN 中的阶段映射

页面阶段 RN 对应
onCreate 组件初始化
onMount useEffect(() => {}, [])
onActive useFocusEffect
onInactive focus cleanup
onDestroy 极少发生

Web 中的阶段映射(不使用 keep-alive)

页面阶段 Web 对应
onCreate setup
onMount mounted
onActive
onInactive
onDestroy unmounted

可以看到,Web 缺失了中间层

Web 中的阶段映射(使用 keep-alive)

页面阶段 Web 对应
onCreate setup
onMount mounted
onActive activated
onInactive deactivated
onDestroy unmounted

这时,Web 才第一次和 RN 站在同一张图上。

一个跨端可复用的页面逻辑示例

定义页面逻辑(与平台无关)

ts 复制代码
class ListPageLogic {
  start() {
    console.log('start polling');
  }

  stop() {
    console.log('stop polling');
  }
}

RN 中使用

js 复制代码
function ListScreen() {
  const logic = useRef(new ListPageLogic()).current;

  useFocusEffect(
    React.useCallback(() => {
      logic.start();
      return () => logic.stop();
    }, [])
  );

  return null;
}

Web 中使用(Vue + keep-alive)

js 复制代码
export default {
  activated() {
    this.logic.start();
  },
  deactivated() {
    this.logic.stop();
  }
};

同一套业务逻辑,只是生命周期绑定点不同。

一个真实业务场景的对齐示例

场景:订单列表轮询

错误模型:

  • mounted 开始轮询
  • unmounted 停止轮询

结果:

  • Web 需要 keep-alive
  • RN 出现后台轮询

统一模型后的写法

  • 页面激活 → 开始轮询
  • 页面失焦 → 停止轮询

平台无关。

这套模型带来的实际好处

1. 页面行为可预测

  • 不再出现"我不在这个页面但它在跑"
  • 副作用边界清晰

2. keep-alive 使用变得理性

你会发现:

  • 有些页面根本不该缓存
  • 有些页面缓存了也不会出问题

3. RN / Web 团队可以真正对齐

  • PR review 维度统一
  • 讨论问题不再纠结"这个端不一样"

一个简单但很重要的团队约定

在跨端项目中,建议强制约定:

禁止在 onMount / mounted 中启动长期副作用

所有长期行为必须绑定:

  • onActive
  • onInactive

总结

跨端路由设计不是选型问题,而是页面模型问题

当你把页面理解为:

一个会在不同阶段切换状态的长期对象

你会发现:

  • RN 不再"特殊"
  • Web 不再"混乱"
  • keep-alive 不再"危险"
相关推荐
fantasy_arch2 小时前
SVT-AV1帧类型决策-场景切换检测
前端·网络·av1
LYFlied2 小时前
前端工程化核心面试题与详解
前端·面试·工程化
小程故事多_802 小时前
用Agent与大模型实现Web项目全自动化生成:从需求到部署的完整落地方案
运维·前端·人工智能·自动化·aigc
千里马-horse2 小时前
AsyncContext
开发语言·前端·javascript·c++·napi·asynccontext
勇往直前plus2 小时前
Jackson 反序列化首字母大写字段映射失败的底层原因与解决方案
java·开发语言·前端
转转技术团队2 小时前
基于微前端 qiankun 多实例保活的工程实践
前端·javascript·前端工程化
松涛和鸣2 小时前
37、UDP网络编程入门
linux·服务器·前端·网络·udp·php
毕设十刻2 小时前
基于Vue的新生入学报道管理系统(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
期待のcode2 小时前
JWT令牌
前端·javascript·spring boot·安全