搜索
您的当前位置:首页正文

使用React如何封装Portal可复用组件

2020-11-27 来源:步旅网

react的核心之一是组件,下面这篇文章主要给大家介绍了关于React教程之封装一个Portal可复用组件的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面一起学习学习吧。

Portal简介

所以我们需要的一个通用组件,它做如下的事情:

  • 可以声明式的写在一个组件中

  • 并不真正render在被声明的地方

  • 支持过渡动画

  • 那么,像modal、tooltip、notification等组件都是可以基于这个组件的。我们叫这个组件为Portal。

    使用了React16+的你,对Portal至少有所了解或者熟练使用。

    Portal可以创建一个在你的root元素之外的DOM。

    1、通常你的网站只有一个root

    <body>
     <p id="root"></p>
    </body>

    2、使用Portal之后,可以变成下面这样

    <body>
     <p id="root"></p>
     <p id="portal"></p>
    </body>

    Portal高阶组件封装

    Portal的demo在官网上可以看到,而我们要实现的是将它封装成一个可以复用的组件。

    目标

    不需要手动在body下面增加HTML,通过组件自己去创建。

    <CreatePortal
     id, //可以传入id
     className, //可以传入className
     style //可以传入style
     >
     此处插入p或者react组件
    </CreatePortal>

    实现方案

    1、创建一个createPortal函数,该函数将会return一个Portal组件

    function createPortal() {
    
    }
    export default createPortal()

    2、创建Portal组件

    import React from 'react'
    import ReactDOM from 'react-dom'
    import PropTypes from 'prop-types'
    function createPortal() {
     class Portal extends React.Component{
     }
     return Portal
    }
    export default createPortal()

    3、render函数实现,用createPortal创建portal。

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

    4、componentDidMount函数实现,将dom添加到body下面

    componentDidMount() {
     document.body.appendChild(this.el);
    }

    5、componentWillUnmount函数实现,清除DOM结构

    componentWillUnmount() {
     document.body.removeChild(this.el)
     }

    6、实现props,包括id、className、style

    constructor(props) {
     super(props)
     this.el = document.createElement('p')
     if (!!props) {
     this.el.id = props.id || false
     if (props.className) this.el.className = props.className
     if (props.style) {
     Object.keys(props.style).map((v) => {
     this.el.style[v] = props.style[v]
     })
     }
     document.body.appendChild(this.el)
     }
    }

    7、完整代码

    import React from 'react'
    import ReactDOM from 'react-dom'
    import PropTypes from 'prop-types'
    function createPortal() {
     class Portal extends React.Component{
     constructor(props) {
     super(props)
     this.el = document.createElement('p')
     if (!!props) {
     this.el.id = props.id || false
     if (props.className) this.el.className = props.className
     if (props.style) {
     Object.keys(props.style).map((v) => {
     this.el.style[v] = props.style[v]
     })
     }
     document.body.appendChild(this.el)
     }
     }
     componentDidMount() {
     document.body.appendChild(this.el);
     }
     componentWillUnmount() {
     document.body.removeChild(this.el)
     }
     render() {
     return ReactDOM.createPortal(
     this.props.children,
     this.el
     )
     }
     }
     Portal.propTypes = {
     style: PropTypes.object
     }
     return Portal
    }
    export default createPortal()

    上面是我整理给大家的,希望今后会对大家有帮助。

    相关文章:

    vuex之详细介绍中文文档

    如何解决Router跨模块跳转问题

    纯js如何生成下拉列表

    Top