探究React v16(二)Portals插槽

8 篇文章 0 订阅

有错误欢迎指正!?

Portals 用来将子节点渲染到父组件 DOM 层次结构之外的 DOM 节点。
使用方法:

ReactDOM.createPortal(child, container)

第一个child参数就是自组建,container就是需要挂载到的dom节点

一. 为什么要有portals

  1. 在React V16之前,子dom节点只能在父dom节点内渲染,所以想重新渲染的话,必须添加一个div,像这样
<div>
   {this.props.children}
</div>
  1. 但是React V16提供了Portals,就不需要必须添加div了,完全可以这么写:
render() {
  return ReactDOM.createPortal(
    this.props.children,
    domNode,
  );
}
  1. 官网的解释为

A typical use case for portals is when a parent component has an overflow: hidden or z-index style, but you need the child to visually “break out” of its container. For example, dialogs, hovercards, and tooltips.

实际意思就是当父组件有hidden或者z-index属性,dialogs, hovercards和tooltips 这一类需要在上层的组件很有可能被遮盖。所以才有Portals这个属性,可以让自组件在父组件的上方不被遮盖。

二. Event事件的处理:事件冒泡

注意: 一个从 portal 内部会触发的事件会一直冒泡至包含 React tree 的祖先。

下面这个是官网的例子:app-root和modal-root是兄弟dom节点

<html>
  <body>
    <div id="app-root"></div>
    <div id="modal-root"></div>
  </body>
</html>

首先,创建一个Modal组件,调用Modal时的父组件为Parent,Parent的父节点为app-root,但是Model挂载在modal-root下面

但是,Parent 组件能够捕获到未被捕获的从兄弟节点 #modal-root 冒泡上来的事件。

const appRoot = document.getElementById('app-root');
const modalRoot = document.getElementById('modal-root');

class Modal extends React.Component {
  constructor(props) {
    super(props);
    this.el = document.createElement('div');
  }

  componentDidMount() {
    // The portal element is inserted in the DOM tree after
    // the Modal's children are mounted, meaning that children
    // will be mounted on a detached DOM node. If a child
    // component requires to be attached to the DOM tree
    // immediately when mounted, for example to measure a
    // DOM node, or uses 'autoFocus' in a descendant, add
    // state to Modal and only render the children when Modal
    // is inserted in the DOM tree.
    modalRoot.appendChild(this.el);
  }

  componentWillUnmount() {
    modalRoot.removeChild(this.el);
  }

  render() {
    return ReactDOM.createPortal(
      this.props.children,
      this.el,
    );
  }

三 . 使用注意
实现createPortals中的dom节点必须是真实的节点,不可以是虚拟节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值