Ben*_*nny 8 javascript reactjs
单击按钮时我希望Modal出现。该Modal组件添加了一个eventListener,因此当您在模态框外部单击时它会关闭。在 React 18 中,点击事件触发是因为按钮点击发生在Modal 渲染之前?如果我改为react 17,这种情况就不会发生。
在这里找到 CodeSandbox 。请注意,当您单击按钮时,show状态设置为 true。然后Modal组件渲染并直接调用close函数。
应用程序.js:
import { useState } from "react";
import Modal from "./Modal";
import "./styles.css";
export default function App() {
const [show, setShow] = useState(false);
const close = () => {
setShow(false);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<button
onClick={(e) => {
setShow(true);
}}
>
Click
</button>
{show && <Modal close={close} />}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
模态.js
import "./styles.css";
import { useRef, useEffect } from "react";
export default function Modal({ close }) {
const ref = useRef(null);
useEffect(() => {
const handleOutsideClick = (e) => {
if (!ref?.current?.contains(e.target)) {
console.log("This one gets called because of the button click", e);
close();
}
};
document.addEventListener("click", handleOutsideClick, false);
return () => {
document.removeEventListener("click", handleOutsideClick, false);
};
}, [close]);
return (
<div ref={ref} className="Modal">
<h1>I'm a Modal!</h1>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
您可以调用event.stopPropagation来防止多个单击处理程序捕获相同的单击事件。
onClick={(e) => {
e.stopPropagation();
setShow(true);
}}
Run Code Online (Sandbox Code Playgroud)
我不知道为什么 React 17 和 18 之间会有所不同。React 使用自己的“合成事件”,并且两个版本之间事件传播/冒泡的发生方式可能有所变化。
它可能与 React 18 中所谓的“自动批处理”有关。 https://github.com/reactwg/react-18/discussions/21
在您的示例中,模态组件使用本机事件处理与document.addEventlistener(). React 18 似乎处理应用程序内部的单击,这会触发状态更改和重新渲染,安装组件Modal,运行挂钩useEffect(),并在单击事件传播到窗口节点之前创建新的事件侦听器。在 React 17 中,事件可能在重新渲染发生之前完成传播。
| 归档时间: |
|
| 查看次数: |
5014 次 |
| 最近记录: |