Native:用 React Native 渲染同一棵组件树
Native 不使用 DOM、AntD 或 Fluent UI。它使用 React Native 控件,但实体、OakComponent、projection、oakPath、关系路径和 execute 层级全部复用。
1. 添加 Native workspace
npx oak-cli add rn native
npm install
当前 CLI 会生成:
npm run start:native:native
npm run build:native:native:android
npm run build:native:native:ios
npm run run:android:native
npm run run:ios:native
工作区包含 Android、iOS、Metro、路由、polyfill 和 Oak 初始化代码。
2. 开发环境
Android 需要:
- JDK;
- Android Studio 与 SDK;
ANDROID_HOME,或native/android/local.properties中的sdk.dir;- 模拟器或开启 USB 调试的设备。
local.properties、签名 keystore、token 和密码不能提交。教程项目也不提交 debug.keystore。
3. Native render 文件
为页面和共享组件增加:
render.native.tsx
render.native.scss
例如 GroupPanel:
import React from 'react';
import TodoList from '@project/components/todo/list';
export default function Render(props) {
const { oakFullpath } = props.data;
return oakFullpath ? (
<TodoList oakPath={`${oakFullpath}.todo$group`} />
) : null;
}
这与 Web/Desktop 的关系挂载完全相同。
4. Group tabs 与 Modal
使用 React Native 控件:
import {
Modal,
Pressable,
SafeAreaView,
ScrollView,
Text,
View,
} from 'react-native';
横向 ScrollView 渲染 Group tabs。选择后挂载:
<GroupPanel oakPath={`${oakFullpath}.${selectedGroupId}`} />
Modal 中挂载 GroupUpsert。取消调用父节点 clean(),保存调用父 Group ListNode 的 execute()。
5. Native Upsert
Group 使用 TextInput:
<TextInput
value={name}
onChangeText={setName}
/>
Todo 使用 TextInput 和 Switch:
<TextInput value={title} onChangeText={setTitle} />
<Switch value={completed} onValueChange={setCompleted} />
这些 setter 定义在共享 index.ts,内部调用 this.update(...)。render 只负责平台交互。
6. TodoList 的关系提交
TodoList Native render 仍通过:
<TodoUpsert oakPath={`${oakFullpath}.${editingTodoId}`} />
保存调用共享 saveTodo(),执行父 Group path,从而让 todo$group 级联绑定 groupId。不要在 Native render 中单独构造 operation。
7. 为什么不能用裸 tsc 判断 render props
Oak render 的 props 由 Oak 编译器注入。直接执行:
npx tsc -p native/tsconfig.json --noEmit
可能把 function Render(props) 报成隐式类型,因为这条命令绕过了 Oak render transform。项目级检查使用:
npm run build
Native 打包使用 Oak CLI 或 Metro。
8. 构建
完整 Android production build:
npm run build:native:native:android
它会生成路由、执行原生依赖 codegen、Metro bundle 和 Gradle release 构建。
如果当前机器没有 Android SDK,可先验证 JS/render 链路:
cd native
npx cross-env NODE_ENV=production OAK_PLATFORM=native react-native bundle \
--entry-file=index.js \
--bundle-output=../node_modules/.cache/oak-tutorial/native/index.android.bundle \
--assets-dest=../node_modules/.cache/oak-tutorial/native/assets \
--dev=false \
--platform=android
看到 Done writing bundle output 和 Done copying assets,说明路由、Oak transform、Native render、Sass 与 JS 依赖已成功打包。它不能代替最终 APK 构建,但能把“代码问题”和“本机 SDK 问题”分开。
9. 验证
- Group tabs 可以横向滚动和切换;
- Group/Todo Modal Upsert 可新增和编辑;
- Todo 保存后关联正确 Group;
- 重启 App 后数据仍存在;
- Android cleartext/network 配置与 Oak access 地址一致;
- Git 中没有
local.properties、keystore 或 bundle 产物。
git add .
git commit -m "feat: add grouped Todo Native workspace"