React教程之封装一个Portal可复用组件的方法


Posted in Javascript onJanuary 02, 2018

Portal简介

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

  • 可以声明式的写在一个组件中
  • 并不真正render在被声明的地方
  • 支持过渡动画

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

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

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

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

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

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

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

Portal高阶组件封装

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

目标

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

<CreatePortal
 id, //可以传入id
 className, //可以传入className
 style //可以传入style
 >
 此处插入div或者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('div')
 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('div')
   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()

总结

createPortal和Provide实现思想类似,用函数式编程的思想来完成目标。如果你觉得这东西有用,拿去用吧。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
ExtJS Grid使用SimpleStore、多选框的方法
Nov 20 Javascript
自写简单JS判断是否已经弹出页面
Oct 20 Javascript
jQuery load方法用法集锦
Dec 06 Javascript
Jquery封装tab自动切换效果的具体实现
Jul 13 Javascript
Javascript实现Web颜色值转换
Feb 05 Javascript
基于jQuery实现带动画效果超炫酷的弹出对话框(附源码下载)
Feb 22 Javascript
ThinkPHP+jquery实现“加载更多”功能代码
Mar 11 Javascript
jQuery EasyUI之验证框validatebox实例详解
Apr 10 jQuery
深入探究node之Transform
Jul 20 Javascript
关于Stream和Buffer的相互转换详解
Jul 26 Javascript
Chrome插件开发系列一:弹窗终结者开发实战
Oct 02 Javascript
js面向对象封装级联下拉菜单列表的实现步骤
Feb 08 Javascript
Node层模拟实现multipart表单的文件上传示例
Jan 02 #Javascript
10行原生JS实现文字无缝滚动(超简单)
Jan 02 #Javascript
js原生实现移动端手指滑动轮播图效果的示例
Jan 02 #Javascript
vue父组件向子组件(props)传递数据的方法
Jan 02 #Javascript
基于wordpress的ajax写法详解
Jan 02 #Javascript
基于Vue的SPA动态修改页面title的方法(推荐)
Jan 02 #Javascript
jq.ajax+php+mysql实现关键字模糊查询(示例讲解)
Jan 02 #Javascript
You might like
PHP Imagick完美实现图片裁切、生成缩略图、添加水印
2016/02/22 PHP
jQuery 获取对象 根据属性、内容匹配, 还有表单元素匹配
2010/05/31 Javascript
将字符串转换成gb2312或者utf-8编码的参数(js版)
2013/04/10 Javascript
高效率JavaScript编写技巧整理
2013/08/23 Javascript
浅析js中的浮点型运算问题
2014/01/06 Javascript
一个简单的jQuery计算器实现了连续计算功能
2014/07/21 Javascript
jQuery统计指定子元素数量的方法
2015/03/17 Javascript
jquery.validate使用时遇到的问题
2015/05/25 Javascript
JS实现的打字机效果完整实例
2016/06/20 Javascript
Bootstrap Table使用方法解析
2016/10/19 Javascript
jQuery实现ToolTip元素定位显示功能示例
2016/11/23 Javascript
微信小程序 Button 组件详解及简单实例
2017/01/10 Javascript
nodejs爬虫初试superagent和cheerio
2018/03/05 NodeJs
深入浅析nuxt.js基于ssh的vue通用框架
2019/05/21 Javascript
超详细的5个Shell脚本实例分享(值得收藏)
2019/08/15 Javascript
VUE渲染后端返回含有script标签的html字符串示例
2019/10/28 Javascript
Preload基础使用方法详解
2020/02/03 Javascript
关于JavaScript中异步/等待的用法与理解
2020/11/18 Javascript
[03:18]【TI9纪实】社区大触GL与木木
2019/08/25 DOTA
python如何实现远程控制电脑(结合微信)
2015/12/21 Python
详解MySQL数据类型int(M)中M的含义
2016/11/20 Python
PyQt5实现无边框窗口的标题拖动和窗口缩放
2018/04/19 Python
详解Python3的TFTP文件传输
2018/06/26 Python
python 常用的基础函数
2018/07/10 Python
对Django 转发和重定向的实例详解
2019/08/06 Python
Python基于xlrd模块处理合并单元格
2020/07/28 Python
python 基于opencv操作摄像头
2020/12/24 Python
台湾良兴购物网:EcLife
2019/12/01 全球购物
公司联欢晚会主持词
2014/03/22 职场文书
四年级评语大全
2014/04/21 职场文书
党的群众路线教育实践活动个人对照检查材料范文
2014/09/25 职场文书
法人代表证明书格式
2014/10/01 职场文书
2014年高三班主任工作总结
2014/12/05 职场文书
圣诞晚会主持词
2015/07/01 职场文书
班主任远程培训研修日志
2015/11/13 职场文书
Python排序算法之插入排序及其优化方案详解
2021/06/11 Python