HarmonyOS 鸿蒙Next中Taro转元服务,目标页未 ready 立即返回导致源页事件层卡死
HarmonyOS 鸿蒙Next中Taro转元服务,目标页未 ready 立即返回导致源页事件层卡死 我的页点击正常:点击–>跳转目标页
源页正常进入隐藏/显示:useDidHide -> useDidShow
目标页正常进入等待渲染结束:正常
目标页正常进入等待加载后立即返回:目标页卡死,无法点击,如果有ScrollView组件可以滑动;
点击卡死,且没打印日志,说明不是代码里的弹层吃点击
结论偏向于:鸿蒙元服务/Taro ASCF 在 navigateTo 目标页 JS 尚未初始化时被返回,中断路由转场后留下了原生层/路由层的事件拦截状态。
这就说明:这说明问题发生在 ASCF/鸿蒙路由原生转场阶段,早于Taro页面JS生命周期,navigateTo 发起 -> 原生开始创建目标页/加载分包/加载 JS -> 用户立刻返回 -> 目标页 JS 没启动 -> 路由中断后源页面事件层异常。
预期行为:即使目标页尚未完成初始化,用户返回后,上一页也应该恢复正常事件响应。
实际行为:上一页可见但点击事件无法继续传递,页面内容区卡死,只有底部原生 tab 可点击。
Dome很简单就可以测试,一个跳转加一个页面。Dome如果需要可以评论。
更多关于HarmonyOS 鸿蒙Next中Taro转元服务,目标页未 ready 立即返回导致源页事件层卡死的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者您好,建议在Taro社区反馈,问题根因是路径位于node_modules@tarojs\plugin-framework-react\dist\runtime.js的AppWrapper的unmount中执行elements.splice(idx, 1)时没有对idx做判断,可以自行修改下。
class AppWrapper extends react.Component {
// ...
unmount(id, cb) {
const elements = this.elements;
const idx = elements.findIndex(item => item.props.tid === id);
// idx大于-1时才执行代码
if (idx > -1) {
elements.splice(idx, 1);
}
this.forceUpdate(cb);
}
// ...
}
更多关于HarmonyOS 鸿蒙Next中Taro转元服务,目标页未 ready 立即返回导致源页事件层卡死的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
能否看下demo呢?
taro通过dev:ascf进行编译,taro版本是3.6.38,然后也进行了分包,下面是在我的页面添加的简易dome,小程序我测试过了页面可以之间打开,元服务中间还有一段js的解析加载过程,会有空白页的情况,在空白页即将消失的时候返回到我的页面,整个页面就会卡住,点击不了。
<View
className={`flex flex_ai_center flex_jc_sb ${styles["entry-item"]}`}
onClick={jumpToAscfRouteBugDemo}
>
<Text>跳转简易dome页</Text>
</View>
const RouteProbe = () => {
const logRouteDebug = (stage: string) => {
console.log("[ascf route bug demo][target]", stage, {
time: Date.now(),
currentPages: Taro.getCurrentPages?.().map((page: any) => page?.route),
});
};
useEffect(() => {
logRouteDebug("useEffect mount");
return () => logRouteDebug("useEffect unmount");
}, []);
useReady(() => {
logRouteDebug("useReady");
});
useDidShow(() => {
logRouteDebug("useDidShow");
});
useDidHide(() => {
logRouteDebug("useDidHide");
});
useUnload(() => {
logRouteDebug("useUnload");
});
return (
<View
style={{ padding: "80px 24px", backgroundColor: "#fff", minHeight: "100vh" }}
onTouchStart={() => logRouteDebug("root onTouchStart")}
onClick={() => logRouteDebug("root onClick")}
>
<Text>Route probe page</Text>
</View>
);
};
export default RouteProbe;
上面写错一个描述,是目标页正常进入等待加载后立即返回:源页卡死,无法点击,如果源页面有ScrollView组件可以滑动;
鸿蒙Next中Taro元服务的页面切换依赖异步ready机制。目标页未完成初始化(未调用ready)便立即返回时,源页的事件调度层无法正确释放等待资源,导致事件循环阻塞,页面卡死。这是页面栈状态机与事件分发时序未对齐的典型表现。
此问题根本原因在于鸿蒙元服务原生路由转场尚未完成时被中断,遗留了事件拦截层。可通过在源页重新显示时强制刷新事件层规避,示例代码如下(Taro 框架):
import { useDidShow, getCurrentInstance } from '@tarojs/taro';
function SourcePage() {
useDidShow(() => {
// 延迟等待原生层释放后,强制触发一次页面渲染以恢复触摸事件分发
const timer = setTimeout(() => {
const instance = getCurrentInstance();
if (instance?.page) {
instance.page.setData({ __touchFlag: Date.now() }); // 触发视图更新
}
}, 150);
return () => clearTimeout(timer);
});
// ... 其他逻辑
}
如果仍无效,可将跳转延时,防止用户在目标页 JS 未初始化时返回:
// 延时 300ms 再 navigateTo,给分包加载留出时间
setTimeout(() => { Taro.navigateTo({ url: '/pages/target/index' }); }, 300);
优先推荐第一种方案,它不改变用户交互节奏。此问题已有对应 Issue 反馈,为临时规避措施。


