
网罗开发 (小红书、快手、视频号同名)
大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验 。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索"展菲",即可纵览我在各大平台的知识足迹。
📣 公众号"Swift社区",每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友"fzhanfei",与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!
文章目录
-
- 摘要
- 一个先抛出来的结论
- 先拆掉一个常见误解
-
- [误解:RN 页面不会被销毁,Web 页面会](#误解:RN 页面不会被销毁,Web 页面会)
- 一个统一的页面阶段模型
- [RN 是怎么强迫你面对这个模型的?](#RN 是怎么强迫你面对这个模型的?)
- [Web 项目为什么一直在逃避这个问题?](#Web 项目为什么一直在逃避这个问题?)
- [keep-alive 的真正作用是什么?](#keep-alive 的真正作用是什么?)
- [统一 RN 与 Web 的关键:抽象"页面阶段"](#统一 RN 与 Web 的关键:抽象“页面阶段”)
- [RN 中的阶段映射](#RN 中的阶段映射)
- [Web 中的阶段映射(不使用 keep-alive)](#Web 中的阶段映射(不使用 keep-alive))
- [Web 中的阶段映射(使用 keep-alive)](#Web 中的阶段映射(使用 keep-alive))
- 一个跨端可复用的页面逻辑示例
- [RN 中使用](#RN 中使用)
- [Web 中使用(Vue + keep-alive)](#Web 中使用(Vue + keep-alive))
- 一个真实业务场景的对齐示例
- 这套模型带来的实际好处
-
- [1. 页面行为可预测](#1. 页面行为可预测)
- [2. keep-alive 使用变得理性](#2. keep-alive 使用变得理性)
- [3. RN / Web 团队可以真正对齐](#3. RN / Web 团队可以真正对齐)
- 一个简单但很重要的团队约定
- 总结
摘要
如果你同时做过 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,每一个页面其实都经历这四个阶段:
- 创建(Create)
- 挂载(Mount)
- 激活(Active / Focus)
- 休眠(Inactive / Blur)
- 销毁(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 不再"危险"