From eb355ef47ed3f7e9e6a0d2b4596f918811cfd6a7 Mon Sep 17 00:00:00 2001 From: Tom Zhai Date: Thu, 11 Jun 2026 20:05:39 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20Modal=20closeAll=20=E5=9C=A8=20onClo?= =?UTF-8?q?se=20=E5=9B=9E=E8=B0=83=E4=B8=AD=E9=80=92=E5=BD=92=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E5=AF=BC=E8=87=B4=E6=A0=88=E6=BA=A2=E5=87=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通过 Modal.show / Modal.confirm 等方法打开的弹窗,若用户在 onClose 回调中调用 Modal.closeAll(),closeAll 内部会再次触发每个弹窗的 onClose,进而递归回到 closeAll,最终抛出 RangeError: Maximum call stack size exceeded。 通过在 closeAll 执行期间增加重入守卫,阻断嵌套调用以中断递归路径。 --- site/pages/documentation/changelog/2.x.x.md | 5 ++--- src/Modal/events.tsx | 22 ++++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/site/pages/documentation/changelog/2.x.x.md b/site/pages/documentation/changelog/2.x.x.md index 1f71a941b..09c114e2e 100644 --- a/site/pages/documentation/changelog/2.x.x.md +++ b/site/pages/documentation/changelog/2.x.x.md @@ -1,9 +1,8 @@ # 更新日志 -### 2.0.33 -- 修复 `Form` 调用 `validateClear` 传入指定字段名时,若对应字段未注册校验器会导致报错的问题 - ### 2.0.32 +- 修复 `Modal` 通过 `Modal.show` 等方法打开的弹窗,在 `onClose` 中调用 `Modal.closeAll` 时会触发无限递归导致栈溢出报错的问题 +- 修复 `Form` 调用 `validateClear` 传入指定字段名时,若对应字段未注册校验器会导致报错的问题 - 修复 `Table` 使用 `treeExpandKeys` 展开树形行时,若数据中包含 DOM 引用等不可序列化字段会导致页面崩溃的问题 - 修复 `Grid` 组件动态生成的样式在微前端场景下被错误劫持导致样式失效的问题 - 修复 `Dropdown` 嵌套使用 `absolute` 时子级菜单项点击无法触发 onClick 的问题(Regression: since 2.0.29) diff --git a/src/Modal/events.tsx b/src/Modal/events.tsx index 2595df93e..8fa23d5a7 100644 --- a/src/Modal/events.tsx +++ b/src/Modal/events.tsx @@ -224,14 +224,22 @@ export const method = (type: Methods) => (option: Options) => { return () => close(props) } +let closingAll = false export const closeAll = () => { - Object.keys(containers) - .filter(id => containers[id].props.from === 'method' && containers[id].visible) - .forEach(id => { - const { onClose, usePortal } = containers[id].props - if (onClose) onClose() - if (!usePortal) close(containers[id].props) - }) + // 防止用户在 onClose 回调中再次调用 closeAll 造成无限递归 + if (closingAll) return + closingAll = true + try { + Object.keys(containers) + .filter(id => containers[id].props.from === 'method' && containers[id].visible) + .forEach(id => { + const { onClose, usePortal } = containers[id].props + if (onClose) onClose() + if (!usePortal) close(containers[id].props) + }) + } finally { + closingAll = false + } } ready(() => { From 09286e6a01ff5f71af294321800ddbdf3b170f85 Mon Sep 17 00:00:00 2001 From: Tom Zhai Date: Thu, 11 Jun 2026 20:10:02 +0800 Subject: [PATCH 2/2] chore: bump version to 2.0.32-beta.5 --- package.json | 2 +- src/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7ed818f8d..cb979f700 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "shineout", - "version": "2.0.32-beta.4", + "version": "2.0.32-beta.5", "description": "Shein 前端组件库", "main": "./lib/index.js", "module": "./es/index.js", diff --git a/src/index.js b/src/index.js index 665aed2ee..bdd6984cb 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ import * as utils from './utils' -export default { utils, version: '2.0.32-beta.4' } +export default { utils, version: '2.0.32-beta.5' } export { utils } export { setLocale } from './locale' export { color, style } from './utils/expose'