第 01 章:一张图看懂 Native Home
1. 它不只是一个原生列表
HomeContainer 是一个“跨平台原生页面引擎”,而 MobileNativeHomeRenderer 是它的 React 控制器。前者负责把 snapshot 变成高性能的 header、tab、section、row 和滚动行为;后者负责读取 Home Store、翻译业务状态、挂载 React slots、处理 intent。
2. 四个层次的职责
| 层 | 代表文件 | 它拥有的真相 | 它刻意不做的事 |
|---|---|---|---|
| 业务语义 | packages/kit/src/views/Home/model、Home Store | loading/ready/error、权限、command revision、owner | 不直接画原生 row |
| ViewModel | mobileNativeHomeViewModelAdapter.ts、MobileNativeHomeRenderer.tsx | tab topology、section、item renderer、command id | 不访问 UIKit/Android API |
| 协议/宿主 | HomeContainer.types.ts、HomeContainer.native.tsx、Nitro | JSON shape、owner、slot metadata、imperative ref | 不理解代币业务 |
| 原生引擎 | HomeContainerView.swift/.kt | viewport、分页、滚动、row layout、图片 | 不决定某个 command 的业务含义 |
这不是“严格的洋葱架构”:顶层 renderer 会直接导入 native component 的类型和组件,因为它必须决定 snapshot 和 slot 组合;但原生层不反向依赖 Home Store,边界仍然清楚。
3. 关键量级与复杂度来源
这份快照中,最能说明复杂度的不是总文件数,而是关键文件的形状:
| 文件 | 规模/信号 | 说明 |
|---|---|---|
HomeContainer.types.ts | 308 行 | 协议定义、渲染类型、owner、ref、不变量都集中在这里 |
HomeContainer.native.tsx | 368 行 | Nitro host、slot flatten、布局尺寸、回调稳定化 |
MobileNativeHomeRenderer.tsx | 1,982 行 | 业务状态到 snapshot/slot/intent 的总装配器 |
mobileNativeHomeViewModelAdapter.ts | 1,687 行 | Portfolio、Market、DeFi、NFT、History、Perps 的展示投影 |
Android HomeContainerView.kt | 4,938 行 | ViewPager2、RecyclerView、手势、各类 row view |
iOS HomeContainerView.swift | 6,236 行 | UIKit 页面、嵌套滚动、tab、各类 cell/control |
这说明项目选择了“协议稳定 + 原生高性能 + JS 业务可变”的路线,而不是把整个 Home 做成一个巨大原生业务模块。
4. 一次更新的完整旅程
5. 最重要的设计判断
HomeContainer 内部不保存“可执行业务动作”;它只保存 actionId、itemId、tabId 和 requestId。这让 native engine 可以被测试、重建和跨平台复用,而不会把钱包导航、交易详情、资产管理等业务逻辑复制到 Swift/Kotlin。
相反,React slot 也不是随意覆盖原生内容:slot 只有在 owner 匹配、host 已布局、并且当前 slot key 出现在 mounted set 中时才真正挂到原生 host。性能优化与安全边界在同一套布局机制里完成。