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 常用到的增,删,改,查操作代码
Dec 28 Javascript
jQuery对象与DOM对象之间的转换方法
Apr 15 Javascript
JavaScript中的View-Model使用介绍
Aug 11 Javascript
ie9 提示'console' 未定义问题的解决方法
Mar 20 Javascript
Javascript中数组方法汇总(推荐)
Apr 01 Javascript
jQuery实现模拟marquee标签效果
Jul 14 Javascript
分享一些常用的jQuery动画事件和动画函数
Nov 27 Javascript
JS实现日期时间动态显示的方法
Dec 07 Javascript
JS短信验证码倒计时功能的实现(没有验证码,只有倒计时)
Oct 27 Javascript
详解jquery validate实现表单验证 (正则表达式)
Jan 18 Javascript
JavaScript脚本语言是什么_动力节点Java学院整理
Jun 26 Javascript
ES2020让代码更优美的运算符 (?.) (??)
Jan 04 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初学入门
2006/11/19 PHP
屏蔽机器人从你的网站搜取email地址的php代码
2012/11/14 PHP
php获取$_POST同名参数数组的实现介绍
2013/06/30 PHP
php ci框架中加载css和js文件失败的解决方法
2014/03/03 PHP
php7 图形用户界面GUI 开发示例
2020/02/22 PHP
javascript生成/解析dom的CDATA类型的字段的代码
2007/04/22 Javascript
Javascript学习笔记7 原型链的原理
2010/01/11 Javascript
jquery实现手风琴效果实例代码
2013/11/15 Javascript
用IE重起计算机或者关机的示例代码
2014/03/10 Javascript
12个超实用的JQuery代码片段
2015/11/02 Javascript
jqGrid用法汇总(全经典)
2016/06/28 Javascript
Laydate时间组件在火狐浏览器下有多时间输入框时只能给第一个输入框赋值的解决方法
2016/08/18 Javascript
深入理解JavaScript定时机制
2016/10/27 Javascript
Node.js中如何合并两个复杂对象详解
2016/12/31 Javascript
微信小程序 限制1M的瘦身技巧与方法详解
2017/01/06 Javascript
详解微信开发中snsapi_base和snsapi_userinfo及静默授权的实现
2017/03/11 Javascript
Vue 表单控件绑定的实现示例
2017/08/11 Javascript
js 获取json数组里面数组的长度实例
2017/10/31 Javascript
vue实现移动端H5数字键盘组件使用详解
2020/08/25 Javascript
关于IDEA中的.VUE文件报错 Export declarations are not supported by current JavaScript version
2020/10/17 Javascript
vue el-upload上传文件的示例代码
2020/12/21 Vue.js
Python中用于返回绝对值的abs()方法
2015/05/14 Python
python3实现ftp服务功能(客户端)
2017/03/24 Python
Python网络编程详解
2017/10/31 Python
Python中利用xpath解析HTML的方法
2018/05/14 Python
关于python写入文件自动换行的问题
2018/06/23 Python
tensorflow 打印内存中的变量方法
2018/07/30 Python
详解Django admin高级用法
2019/11/06 Python
Python 连接 MySQL 的几种方法
2020/09/09 Python
python matlab库简单用法讲解
2020/12/31 Python
机修工工作职责
2014/02/21 职场文书
班组长岗位职责
2014/03/03 职场文书
大四毕业生自荐书
2014/07/05 职场文书
2019年英语版感谢信(8篇)
2019/09/29 职场文书
Python爬虫基础讲解之请求
2021/05/13 Python
vue中的可拖拽宽度div的实现示例
2022/04/08 Vue.js