Skip to content

Conversation

@Gaubee
Copy link
Contributor

@Gaubee Gaubee commented Jan 4, 2026

问题描述

启动小程序后,切换底部 Tab 离开生态页再切回,小程序窗口变为不可见(opacity: 0)。

根本原因

  1. MiniappWindowStackflowApp 全局层渲染,通过 createPortal 把内容传送到 MiniappWindowStack 的 slot 中
  2. MiniappWindowStackEcosystemDesktop 内,被 Activity mode='hidden' 包裹
  3. 当 Tab 切走时,Activity 可能暂停组件,导致 slot 被注销
  4. MiniappWindowPortal 获取不到 portalHost,返回 null 或动画到错误位置

解决方案

方案 1: Slot 生命周期机制

  • runtime-refs.ts 中添加 slot 状态管理(slotStatusMap
  • 添加 useSlotStatus hook 订阅 slot 状态
  • MiniappWindowPortal 当 slot lost 时使用 fallback 容器,禁用 layoutId

方案 2: 避免 Activity 包裹 EcosystemTab

  • 使用 display: none 替代 Activity mode='hidden' 控制 EcosystemTab 可见性
  • 组件保持完全挂载,slot 不会被注销

变更文件

  • src/services/miniapp-runtime/hooks.ts - 新增 useMiniappVisibilityRestoreuseSlotStatus
  • src/services/miniapp-runtime/runtime-refs.ts - 添加 slot 状态管理
  • src/components/ecosystem/miniapp-window.tsx - 使用 slot 状态控制渲染
  • src/stackflow/activities/MainTabsActivity.tsx - EcosystemTab 使用 display:none
  • src/StackflowApp.tsx - 添加 fallback 容器
  • src/components/ecosystem/miniapp-window.stories.tsx - 添加 Tab 切换测试

Gaubee added 3 commits January 4, 2026 12:06
When switching bottom tabs away from ecosystem and back, the miniapp
window became invisible (opacity 0) because:
1. EcosystemTab uses React 19 <Activity mode='hidden'> which unmounts/pauses the child tree
2. MiniappWindowStack slots get unregistered when unmounted
3. But runtime app state remained 'active' with no re-activation on return

Fix: Call activateApp() when EcosystemTab remounts to restore the
active miniapp's visibility state.

Adds E2E regression test for tab-switch visibility.
Add slot status management in runtime-refs.ts:
- slotStatusMap tracks slot ready/lost state
- subscribeSlotStatus() for React subscription
- getSlotStatus() for querying

Add useSlotStatus hook using useSyncExternalStore

MiniappWindowPortal now:
- Subscribes to slot status
- Uses fallback container when slot lost
- Disables layoutId when slot lost to prevent animation issues
- Sets visibility:hidden when slot lost

This fixes miniapp becoming invisible after tab switch.
Replace Activity mode='hidden' with display:none for EcosystemTab to
prevent MiniappWindowStack slots from being unregistered during tab
switch. This ensures miniapp windows remain visible after switching
tabs away from ecosystem and back.

Activity mode='hidden' may pause/unmount components causing slot
unregistration, while display:none keeps the component fully mounted.
@Gaubee Gaubee merged commit 0809bcd into main Jan 4, 2026
5 checks passed
@Gaubee Gaubee deleted the fix/miniapp-tab-visibility-v2 branch January 4, 2026 06:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants