Repository navigation
Conversation
| setFocusedNavigation(navigation) | ||
| pageStatusMap[pageId] = 'show' | ||
| }) | ||
| if (navigation.isFocused()) Promise.resolve().then(show) |
| if (navigation.isFocused && navigation.isFocused()) { | ||
| Promise.resolve().then(() => { | ||
| const show = () => { | ||
| if (navigation.isFocused()) { |
There was a problem hiding this comment.
navigation.isFocused的判断还需要保留
| const { navigation, route } = props | ||
| const currentPageId = useMemo(() => ++pageId, []) | ||
| const routeContextValRef = useRef({ navigation, pageId: currentPageId }) | ||
| const routeContextValue = useMemo(() => ({ navigation, pageId: currentPageId }), [navigation, currentPageId]) |
There was a problem hiding this comment.
即使会更新也直接修改ref的值即可,不需要创建新的context触发订阅刷新
| const { navigation, route } = props | ||
| const currentPageId = useMemo(() => ++pageId, []) | ||
| const routeContextValRef = useRef({ navigation, pageId: currentPageId }) | ||
| const routeContextValue = useMemo(() => ({ navigation, pageId: currentPageId }), [navigation, currentPageId]) |
There was a problem hiding this comment.
即使会更新也直接修改ref的值即可,不需要创建新的context触发订阅刷新
|
|
||
| if (type === 'page') { | ||
| const props = propsRef.current | ||
| const wasPreloaded = !!props.navigation.getState?.()?.preloadedRoutes?.some(route => route.key === props.route.key) |
There was a problem hiding this comment.
作为onLoad的第三个参数 isPreload即可,不需要挂载实例属性
| return () => { | ||
| unWatch && unWatch() | ||
| if (type === 'page') { | ||
| del(pageStatusMap, pageId) |
hiyuki
left a comment
There was a problem hiding this comment.
基于 dc929c2 的评审,发现两个需要处理的问题,见行内评论。
navigation 更新及保留 pageStatus 的修改有依据:React Navigation 明确说明预加载页面正式进入时会更新 navigation。针对性测试中,实例复用、onLoad 只执行一次、首次 onShow 前领取 EventChannel 均正常。
验证:变更文件 ESLint 通过,47 项相关及针对性测试通过。针对性测试位于临时评审快照中,使用 RN mock,未进行真机验证。
| return | ||
| } | ||
| const finalPath = resolvePath(path, getBasePath(navigation)).slice(1) | ||
| navigation.preload(finalPath, queryObj) |
There was a problem hiding this comment.
[P2] 预加载页会提前覆盖当前页的状态栏样式
调用 preload 后,目标页的 pageWrapperHOC → MpxNav 会挂载,而 MpxNav 无条件渲染 StatusBar。例如 A 配置 navigationBarTextStyle: 'white'、B 配置 'black',在 A 预加载 B 后,尚未跳转就会被 B 覆盖。针对性测试确认了未聚焦的 B 仍追加 StatusBar;RN 的状态栏属性按组件挂载顺序合并:https://reactnative.dev/docs/statusbar#usage-with-navigator 。
建议让状态栏配置随页面焦点生效,并覆盖多个预加载页面的场景。
| ## 注意事项 {#notes} | ||
|
|
||
| - 预加载会提前执行 `onLoad`,但不触发 `onShow/onHide`。正式进入并复用该页面时触发 `onShow`,不重复执行 `onLoad`。 | ||
| - RN 的 `onLoad(query, decodedQuery, isPreload)` 第三个参数表示本次初始化是否发生在预加载阶段;普通打开或入栈后才初始化时为 `false`。前两个参数保持原有含义,分别为原始 query 和解码后的 query。 |
There was a problem hiding this comment.
[P3] 补齐文档入口及 Skill 同步
新增 preload.md 后,还需要在 docs-vitepress/.vitepress/config.ts 的路由 API 侧边栏添加入口,并同步 .agents/skills/mpx/references/rn/rn-api-reference.md、rn-script-reference.md 及相关索引,说明 preload、onLoad 第三个参数 isPreload,以及 EventChannel 的获取时机。当前 PR 未包含这些更新,文档缺少侧边栏入口,Skill 也无法反映新增能力;这也是仓库 AGENTS.md 要求在同一次改动中同步的内容。
新增
mpx.preload({ url }): void,允许停留在当前页面时提前创建目标页面,并通过 RN 的onLoad第三个参数isPreload标识本次是否为预加载初始化。修复预加载实例正式进入后缺失onShow、navigation 引用未同步及 EventChannel 交接问题。例如 A 预加载 B,再 navigateTo B 时,复用同一实例,在首次 onShow 领取正式跳转创建的 EventChannel,正式聚焦触发 onShow,onLoad 不重跑。无 getId 时沿用 React Navigation 的同名候选复用规则,正式跳转参数可能与初始化参数不同。
改动