React Portal 之事件冒泡

实现一个日历选择器,其中日历部分是一个弹层,有个常见的需求时,当点击日历框之外的部分,则日历框消失。而其中日历框是处于一个React.createPortal()创造出来的结构中,而日历框因为兼容移动端和online端,又会有两个组件CalendarMobileCalendarPC.

大致的嵌套结构是:

CheckDate
  DateInput
  CalendarMobile       -- Portal
    or
  CalendarPC           -- Portal

其中DateInput点击之后,Portal组件出现,点击Portal组件内部不做处理,点击Portal之外关闭Portal

基于React事件处理的知识,之前的实现是: 1. 在window上添加click事件监听,在监听到click之后触发关闭弹层。 2. CalendarMobileCalendarPC组件上最顶层使用e.nativeEvent.stopImmediatePropagation阻止事件冒泡至window,也就不会触发到window上的事件了。 3. DateInput上也添加e.nativeEvent.stopImmediatePropagation阻止冒泡。

但是后来发现可以在CheckDate组件中统一处理,查看相关文档

尽管portal可以在DOM的任意位置,但是它就表现的跟正常Reach child一样,像 Context 还是正常的工作,因为 portal依然存在于 React Tree,而不在意实际在DOM中的位置 同样 Event 冒泡也是一样的,portal 内部触发的事件依然会传递到React Tree中的祖先组件中,尽管祖先组件在DOM tree中并不是 portal 组件的祖先元素。

示例代码

Last updated