美文网首页
02-react-传送门Portals的简介和使用

02-react-传送门Portals的简介和使用

作者: 低头看云 | 来源:发表于2020-10-13 09:10 被阅读0次

Portals

Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。

ReactDOM.createPortal(child, container)

第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或 fragment。

第二个参数(container)是一个 DOM 元素。

应用场景: 对话框、悬浮卡以及提示框:

实列

实现一个modal

import React, { PureComponent } from 'react'

import { createPortal } from 'react-dom'

class Modal extends PureComponent {
  constructor(props) {
    super(props)
    const doc = window.document
    console.log('window.document', window.document)
    this.node = doc.createElement('div')
    doc.body.appendChild(this.node)
  }
  componentWillUnmount() {
    window.document.body.removeChild(this.node)
  }
  render() {
      //  React 并*没有*创建一个新的 div。它只是把子元素渲染到 `domNode` 中。
  // `domNode` 是一个可以在任何位置的有效 DOM 节点。
    return createPortal(
      <div className="mask">
        <div className="modal">
          <h3>Modal</h3>
          {this.props.children}
        </div>
      </div>,
      this.node
    )
  }
}

export default Modal

  • 目录结构
image-20201012134405623

通过 Portal 进行事件冒泡

尽管 portal 可以被放置在 DOM 树中的任何地方,但在任何其他方面,其行为和普通的 React 子节点行为一致。由于 portal 仍存在于 React 树, 且与 DOM 树 中的位置无关,那么无论其子节点是否是 portal,像 context 这样的功能特性都是不变的。

这包含事件冒泡。一个从 portal 内部触发的事件会一直冒泡至包含 React 树的祖先,即便这些元素并不是 DOM 树 中的祖先。假设存在如下 HTML 结构:

import React, { PureComponent } from 'react'
import Modal from '../../components/Modal'

class MyModal extends PureComponent {
  state = {
    count: 0,
  }
  handleClick = () => {
    this.setState({
      count: this.state.count + 1,
    })
  }
  render() {
    return (
      <div
        onClick={this.handleClick}
        style={{
          height: '100%',
        }}
      >
        我是测试
        <p>点击次数{this.state.count}</p>
        <Modal>
          <div>我是Modal</div>
        </Modal>
      </div>
    )
  }
}

export default MyModal

image-20201012134554207

相关文章

网友评论

      本文标题:02-react-传送门Portals的简介和使用

      本文链接:https://www.haomeiwen.com/subject/rkwupktx.html