fix: 修复 Modal 在 onClose 中调用 closeAll 导致栈溢出的问题 - #2219
Merged
Merged
Conversation
通过 Modal.show / Modal.confirm 等方法打开的弹窗,若用户在 onClose 回调中调用 Modal.closeAll(),closeAll 内部会再次触发每个弹窗的 onClose,进而递归回到 closeAll,最终抛出 RangeError: Maximum call stack size exceeded。 通过在 closeAll 执行期间增加重入守卫,阻断嵌套调用以中断递归路径。
saint3347
force-pushed
the
fix/modal-closeall-infinite-recursion
branch
from
June 11, 2026 12:10
f30fe95 to
09286e6
Compare
Contributor
Author
后续修复本 PR 通过 但 PR #1908 (commit 76cba77) 引入的「 #2220 通过将 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题描述
通过
Modal.show/Modal.confirm等方法打开的弹窗,若业务在onClose回调中调用Modal.closeAll(),点击右上角关闭图标时浏览器会抛出:弹窗无法关闭,页面卡死,必须刷新才能恢复。该问题在 v1 下不存在,属于 v2 的回归问题。
复现路径
site/pages/components/Modal/example-1-base.tsx:点击 Modal 右上角 X 即触发栈溢出。
根因分析
v2 自 #1908 起,
closeAll在关闭每个弹窗前会主动调用其onClose回调(v1 不会)。当用户的onClose内部又调closeAll时,链路变为:由于
close()尚未执行,弹窗的visible仍为true,每一层closeAll都能找到同一个弹窗继续递归,最终爆栈。修复方案
在
closeAll执行期间增加重入守卫,嵌套调用直接 return,阻断递归路径。修复对正常的closeAll调用、ESC 关闭、确认按钮关闭等其它路径无任何影响。影响范围
src/Modal/events.tsx:closeAll增加重入守卫site/pages/documentation/changelog/2.x.x.md:2.0.32 段新增 changelog 条目