【发布时间】:2021-06-09 10:59:10
【问题描述】:
我正在制作一个 React 应用程序,其中我制作了一个自定义 DatePicker 组件。如果发生外部点击,我希望它被隐藏(就像我对其他组件所做的那样,例如 Select Dropdown)。长话短说,我写了一个自定义钩子:
export default (ref, visible, setVisible) => {
React.useEffect(() => {
let handleClick;
if (visible) {
handleClick = (e) => {
if (ref.current && !ref.current.contains(e.target)) {
setVisible((prevVisible) => !prevVisible);
}
};
document.addEventListener('click', handleClick);
}
return () => {
document.removeEventListener('click', handleClick);
};
}, [visible]);
};
问题是当我将它与 Select 组件一起使用时,该组件将其项目作为直接子项,一切正常,但使用 DatePicker,它在选择日期后关闭。这是因为 day 元素本身是我的日历容器的 REF 的内部子元素。结构是这样的:
<div class="picker">
* A <p> tag here for triggering the visibility state *
<div className="calendar" ref={calendar}>
<div className="month">
<div className="week">
<div className="day">
* day number *
</div>
* More days *
</div>
* More weeks *
</div>
* Second month *
</div>
</div>
在 MDN 文档中,我读到 ref.current.contains 应该遍历所有子元素,但它以某种方式仅检查具有“MONTH”类的 div,即仅直接子元素。有没有人遇到过同样的问题?我将不胜感激任何帮助!谢谢!
P.S 这是打开 DatePicker 组件后我的 DOM 树的图像:
【问题讨论】:
-
引用传递给什么元素?
-
@evolutionxbox 包含两个月块内的日历元素(因为我制作了日期范围选择器)和控制按钮(上面的示例中没有)。附言检查上面的伪 jsx/html 标记代码示例,将 ref 属性传递给带有日历类名的 div
-
在
.calendar中单击的任何元素都将导致ref.current.contains(e.target)成为true。 -
@evolutionxbox 突然之间,情况并非如此。不知何故,当我点击
.month(因为我有填充)或.weekconsole.log(ref.current.contains(e.target))返回true,但是当我点击.day时,它们被放置在.week容器内,我不知何故在同一console.log(ref.current.contains(e.target))上获取false -
那么
.week不是.calendar的后代?
标签: javascript html reactjs