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 相关文章推荐
强大的jquery插件jqeuryUI做网页对话框效果!简单
Apr 14 Javascript
为EasyUI的Tab标签添加右键菜单的方法
Jul 14 Javascript
window.onload和$(function(){})的区别介绍
Oct 30 Javascript
Jquery实现Div上下移动示例
Apr 23 Javascript
使用jquery组件qrcode生成二维码及应用指南
Feb 22 Javascript
node作为中间服务层如何发送请求(发送请求的实现方法详解)
Jan 02 Javascript
js实时监控文本框输入字数的实例代码
Jan 18 Javascript
浅谈vue项目重构技术要点和总结
Jan 23 Javascript
jquery 动态遍历select 赋值的实例
Sep 12 jQuery
angular学习之动态创建表单的方法
Dec 07 Javascript
微信小程序选择图片控件
Jan 19 Javascript
使用Canvas绘制一个游戏人物属性图
Mar 25 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
对javascript和select部件的结合运用
2006/10/09 PHP
PHP Array交叉表实现代码
2010/08/05 PHP
php计算数组不为空元素个数的方法
2014/01/27 PHP
win7 64位系统 配置php最新版开发环境(php+Apache+mysql)
2014/08/15 PHP
跟我学Laravel之请求(Request)的生命周期
2014/10/15 PHP
php smtp实现发送邮件功能
2017/06/22 PHP
对象特征检测法判断浏览器对javascript对象的支持
2009/07/25 Javascript
JS控制显示隐藏兼容问题(IE6、IE7、IE8)
2010/04/01 Javascript
用Jquery实现多级下拉框无刷新的联动
2010/12/22 Javascript
jquery实现弹出层遮罩效果的简单实例
2014/03/03 Javascript
JavaScript也谈内存优化
2014/06/06 Javascript
JavaScript中的splice()方法使用详解
2015/06/09 Javascript
JavaScript九九乘法口诀表的简单实现
2016/10/04 Javascript
常用原生js自定义函数总结
2016/11/20 Javascript
vue2.0实战之使用vue-cli搭建项目(2)
2017/03/27 Javascript
node.js通过axios实现网络请求的方法
2018/03/05 Javascript
通过实例了解Nodejs模块系统及require机制
2020/07/16 NodeJs
基于VSCode调试网页JavaScript代码过程详解
2020/07/20 Javascript
vue自定义指令限制输入框输入值的步骤与完整代码
2020/08/30 Javascript
python中zip()方法应用实例分析
2016/04/16 Python
python数据类型判断type与isinstance的区别实例解析
2017/10/31 Python
小白如何入门Python? 制作一个网站为例
2018/03/06 Python
python如何统计序列中元素
2020/07/31 Python
python dataframe astype 字段类型转换方法
2018/04/11 Python
PyQt5每天必学之切换按钮
2020/08/20 Python
Django框架安装方法图文详解
2019/11/04 Python
详解python中的lambda与sorted函数
2020/09/04 Python
python修改微信和支付宝步数的示例代码
2020/10/12 Python
优秀毕业生找工作自荐信
2014/06/23 职场文书
诚信考试标语
2014/06/24 职场文书
幼儿园安全生产月活动总结
2014/07/05 职场文书
创先争优宣传标语
2014/10/08 职场文书
人力资源部岗位职责
2015/02/11 职场文书
2015年安全生产工作总结范文
2015/04/02 职场文书
python 如何获取页面所有a标签下href的值
2021/05/06 Python
Fluentd搭建日志收集服务
2022/09/23 Servers