我的应用程序有一个名为Open Modal
. 单击此按钮时,将向document.body
using附加一个模式createPortal
。演示链接
一旦安装了模式(即isOpen === true
),我想在每次用户单击页面上的某个位置时将一些文本打印到控制台。
为此,我使用useEffect
钩子将点击事件绑定到document
对象,如果isOpen === true
:
useEffect(() => {
const eventHandler = () => console.log("You clicked me");
if (isOpen) {
document.addEventListener("click", eventHandler);
}
}, [isOpen]);
当用户第一次点击“Open Modal”时,isOpen
从false
变为true
,这会导致组件重新渲染。重新渲染完成后,注册上述效果中的点击事件。
问题
第一次单击 'Open Modal' 会document
触发 'click 事件(您可以在控制台中看到事件处理程序的输出)。这对我来说没有意义 -当第一次“打开模式”点击传播到它时,点击事件怎么可能已经注册?document
预期行为
第一次点击 'Open Modal' 只会导致document
'click 事件被注册,此时事件本身不应触发。
如果我省略createPortal
(参见演示的第 38 行),应用程序将按预期工作,即在第一次单击“打开模式”时注册事件,并在页面上的所有后续单击时调用事件处理程序。
如果我将模式安装到应用程序根目录的同级而不是document.body
(参见演示的第 39 行),该应用程序也可以按预期工作。所以上面描述的问题只有在createPortal
使用 withdocument.body
作为容器时才会出现,但我不明白为什么。