Javascript 为什么设置react select的菜单选择状态使模式关闭状态?
我有一个模态,它监听模态的外部点击,并触发onclose方法关闭模态。现在我将react select添加到模式中,在选择其中一个选项后,它将使我的模式处于关闭状态。 我正在从一篇媒体文章中捕获外部点击Javascript 为什么设置react select的菜单选择状态使模式关闭状态?,javascript,reactjs,react-select,Javascript,Reactjs,React Select,我有一个模态,它监听模态的外部点击,并触发onclose方法关闭模态。现在我将react select添加到模式中,在选择其中一个选项后,它将使我的模式处于关闭状态。 我正在从一篇媒体文章中捕获外部点击 function useOuterClickNotifier(onOuterClick, innerRef) { useEffect(() => { if (innerRef.current) { document.addEventListener("click",
function useOuterClickNotifier(onOuterClick, innerRef) {
useEffect(() => {
if (innerRef.current) {
document.addEventListener("click", handleClick);
}
return () => document.removeEventListener("click", handleClick);
function handleClick(e) {
if (innerRef.current && !innerRef.current.contains(e.target)) {
onOuterClick(e);
}
}
}, [onOuterClick, innerRef]);
}
我的index.js
我认为这是由于在调用钩子的事件侦听器时,选择菜单已经卸载。React不知道手动附加的单击处理程序,因此它将立即开始更新DOM。在侦听器处理事件时,单击的DOM节点已经被删除 为了防止出现这种情况,可以将true作为第三个参数传递给addEventListener和removeEventListener。此参数为useCapture。如果为true,它将在捕获阶段在目标元素的任何侦听器之前调用您的侦听器 : useCapture[可选] 一个布尔值,指示是否将此类型的事件分派给 在发送到任何EventTarget之前注册的侦听器 在它下面的DOM树中。正在向上冒泡的事件 树不会触发指定使用捕获的侦听器。事件 冒泡和捕获是传播发生的事件的两种方式 在嵌套在另一个元素中的元素中,当 元素已注册该事件的句柄。事件 传播模式确定元素接收信息的顺序 事件有关详细信息,请参见DOM级别3事件和JavaScript事件顺序 详细解释。如果未指定,useCapture默认为false
我认为问题在于事件正在传播到模态函数。因此,我们需要停止从选择component@DILEEPTHOMAS这不应该是问题所在,因为正在检查事件的目标是否在模式之外。由于某种原因,检查返回false。@trixn我已经发布了一个答案,您能验证它吗?因为我认为事件正在冒泡,所以它调用closeModal函数。如果答案有任何错误,请告诉我,以便我可以更新或删除itI。我使用改进的解决方案更新了我的答案,使其能够侦听单击事件。这个解决方案更好地解决了最初的问题,所以我同意。mousedown也是可能的,但它的行为稍有不同,也不会保护您免受第三方组件监听mousedown的影响。
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import Select from "react-select";
import Modal from "../Modal";
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
];
function App() {
const [isOpen, setOpen] = useState(false);
function onCloseModal() {
console.log("Why closing?");
setOpen(false);
}
function openModal() {
setOpen(true);
}
return (
<>
{isOpen && (
<Modal closeModal={onCloseModal}>
<div className="card">
<Select options={options} />
</div>
</Modal>
)}
<button onClick={openModal}>Open modal</button>
</>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
System:
OS: macOS 10.14.5
CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
Binaries:
Node: 12.4.0 - ~/.nvm/versions/node/v12.4.0/bin/node
Yarn: 1.16.0 - ~/.nvm/versions/node/v12.4.0/bin/yarn
npm: 6.9.0 - ~/.nvm/versions/node/v12.4.0/bin/npm
Browsers:
Chrome: 78.0.3904.97
Firefox: 69.0
Safari: 12.1.1
npmPackages:
react: 16.11.0 => 16.11.0
react-dom: 16.11.0 => 16.11.0
react-scripts: 3.2.0 => 3.2.0
function useOuterClickNotifier(onOuterClick, innerRef) {
useEffect(() => {
if (innerRef.current) {
document.addEventListener("click", handleClick, true);
}
return () => document.removeEventListener("click", handleClick, true);
function handleClick(e) {
if (innerRef.current && !innerRef.current.contains(e.target)) {
onOuterClick(e);
}
}
}, [onOuterClick, innerRef]);
}