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 相关文章推荐
javascript学习笔记(五) Array 数组类型介绍
Jun 19 Javascript
分享XmlHttpRequest调用Webservice的一点心得
Jul 20 Javascript
解析Jquery中如何把一段html代码动态写入到DIV中(实例说明)
Jul 09 Javascript
jquery实现点击展开列表同时隐藏其他列表
Aug 10 Javascript
使用JavaScript实现ajax的实例代码
May 11 Javascript
node.js实现快速截图
Aug 27 Javascript
Angularjs CURD 详解及实例代码
Sep 14 Javascript
jquery实现下拉框左右选择功能
Feb 21 Javascript
基于Bootstrap实现城市三级联动
Nov 23 Javascript
详解从vue-loader源码分析CSS Scoped的实现
Sep 23 Javascript
JavaScript中的this妙用实例分析
May 09 Javascript
javascript实现时间日期的格式化的方法汇总
Aug 06 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 网页播放器用来播放在线视频的代码(自动判断并选择视频文件类型)
2010/06/03 PHP
PHP的加密方式及原理
2012/06/14 PHP
php连接mssql数据库的几种方法
2013/02/21 PHP
『PHP』PHP截断函数mb_substr()使用介绍
2013/04/22 PHP
解析PHP实现下载文件的两种方法
2013/07/05 PHP
CentOS 6.3下安装PHP xcache扩展模块笔记
2014/09/10 PHP
PHP中error_reporting()用法详解
2015/08/31 PHP
php单链表实现代码分享
2016/07/04 PHP
PHP中静态变量的使用方法实例分析
2016/12/01 PHP
php+redis实现商城秒杀功能
2020/11/19 PHP
PHP设计模式之状态模式定义与用法详解
2018/04/02 PHP
PHP判断是否微信访问的方法示例
2019/03/27 PHP
Dreamweaver jQuery智能提示插件,支持版本提示,支持1.6api
2011/07/31 Javascript
js常用自定义公共函数汇总
2014/01/15 Javascript
JavaScript格式化日期时间的方法和自定义格式化函数示例
2014/04/04 Javascript
jquery中map函数与each函数的区别实例介绍
2014/06/23 Javascript
AngularJs 指令详解及示例代码
2016/09/01 Javascript
JavaScript数据结构之二叉树的计数算法示例
2017/04/13 Javascript
jQuery封装placeholder效果实现方法,让低版本浏览器支持该效果
2017/07/08 jQuery
使用JS和canvas实现gif动图的停止和播放代码
2017/09/01 Javascript
利用JQUERY实现多个AJAX请求等待的实例
2017/12/14 jQuery
如何使用CSS3和JQuery easing 插件制作绚丽菜单
2019/06/18 jQuery
vuex存值与取值的实例
2019/11/06 Javascript
详解Tensorflow数据读取有三种方式(next_batch)
2018/02/01 Python
Django使用AJAX调用自己写的API接口的方法
2019/03/06 Python
python中PS 图像调整算法原理之亮度调整
2019/06/28 Python
执行Django数据迁移时报 1091错误及解决方法
2019/10/14 Python
pandas的相关系数与协方差实例
2019/12/27 Python
使用python matploblib库绘制准确率,损失率折线图
2020/06/16 Python
美国鲜花递送:UrbanStems
2021/01/04 全球购物
社区中秋节活动方案
2014/01/29 职场文书
人力资源经理的岗位职责
2014/03/02 职场文书
本科应届生自荐信
2014/06/29 职场文书
php字符串倒叙
2021/04/01 PHP
opencv深入浅出了解机器学习和深度学习
2022/03/17 Python
vue整合百度地图显示指定地点信息
2022/04/06 Vue.js