fix(miniapp-runtime): enter same page twice then exit should not throw error (#7104)
Publish canary / Check Changeset exists (push) Waiting to run Details
Publish canary / Publish Canary (18) (push) Blocked by required conditions Details
CI / build (16.x, ubuntu-latest) (push) Waiting to run Details
CI / build (16.x, windows-latest) (push) Waiting to run Details
CI / build (18.x, ubuntu-latest) (push) Waiting to run Details
CI / build (18.x, windows-latest) (push) Waiting to run Details
Version / Version (16) (push) Waiting to run Details

This commit is contained in:
XGHeaven 2025-06-04 21:11:02 +08:00 committed by GitHub
parent 3670eadc31
commit d27ad76cad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 15 additions and 8 deletions

View File

@ -0,0 +1,5 @@
---
'@ice/miniapp-runtime': patch
---
fix: enter same page twice then exit should not throw error

View File

@ -1,5 +1,5 @@
import { isArray, isFunction, hooks } from '@ice/shared';
import type { PageLifeCycle } from '../dsl/instance.js';
import type { Instance, PageLifeCycle, PageProps } from '../dsl/instance.js';
import type { Func } from '../interface/index.js';
import {
getPageInstance,
@ -13,20 +13,20 @@ const createIceMiniappHook = (lifecycle: keyof PageLifeCycle | string) => {
return (fn: Func) => {
const { R: React, PageContext } = reactMeta;
const id = React.useContext(PageContext) || HOOKS_APP_ID;
const instRef = React.useRef<Instance<PageProps>>();
// hold fn ref and keep up to date
const fnRef = React.useRef(fn);
if (fnRef.current !== fn) fnRef.current = fn;
React.useLayoutEffect(() => {
let inst = getPageInstance(id);
let inst = instRef.current = getPageInstance(id);
let first = false;
if (inst == null) {
if (!inst) {
first = true;
inst = Object.create(null);
instRef.current = Object.create(null);
inst = instRef.current!;
}
inst = inst!;
// callback is immutable but inner function is up to date
const callback = (...args: any) => fnRef.current(...args);
@ -43,13 +43,15 @@ const createIceMiniappHook = (lifecycle: keyof PageLifeCycle | string) => {
injectPageInstance(inst!, id);
}
return () => {
const inst = getPageInstance(id);
const inst = instRef.current;
if (!inst) return;
const list = inst![lifecycle];
if (list === callback) {
(inst![lifecycle] as any) = undefined;
} else if (isArray(list)) {
(inst![lifecycle] as any) = list.filter(item => item !== callback);
}
instRef.current = undefined;
};
}, [id]);
};

View File

@ -130,7 +130,7 @@ export function createPageConfig(
this.config = miniappPageConfig || {};
// this.$icePath 是页面唯一标识
const uniqueOptions = Object.assign({}, options);
const uniqueOptions = Object.assign({}, options, { $iceTimestamp: Date.now() });
const $icePath = this.$icePath = getPath(id, uniqueOptions);
// this.$iceParams 作为暴露给开发者的页面参数对象,可以被随意修改
if (this.$iceParams == null) {