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 表格插件整理
Apr 27 Javascript
jQuery实现的类flash菜单效果代码
May 17 Javascript
javascript下对于事件、事件流、事件触发的顺序随便说说
Jul 17 Javascript
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
Nov 19 Javascript
JavaScript中判断整字类型最简洁的实现方法
Nov 08 Javascript
值得分享的Bootstrap Ace模板实现菜单和Tab页效果
Dec 30 Javascript
JS ES6中setTimeout函数的执行上下文示例
Apr 27 Javascript
jQuery实现参数自定义的文字跑马灯效果
Aug 15 jQuery
详解jQuery设置内容和属性
Apr 11 jQuery
layui动态表头的实现代码
Aug 22 Javascript
JS秒杀倒计时功能完整实例【使用jQuery3.1.1】
Sep 03 jQuery
前端监听websocket消息并实时弹出(实例代码)
Nov 27 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
被jQuery折腾得半死,揭秘为何jQuery为何在IE/Firefox下均无法使用
2010/01/22 Javascript
jquery操作cookie插件分享
2014/01/14 Javascript
javascript 获取函数形参个数
2014/07/31 Javascript
使用jquery解析XML的方法
2014/09/05 Javascript
jQuery中prevUntil()方法用法实例
2015/01/08 Javascript
jQuery中trigger()方法用法实例
2015/01/19 Javascript
javascript自动切换焦点控制效果完整实例
2016/02/02 Javascript
基于RequireJS和JQuery的模块化编程日常问题解析
2016/04/14 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
2016/08/24 Javascript
javascript实现无法关闭的弹框
2016/11/27 Javascript
vue实现简单表格组件实例详解
2017/04/16 Javascript
vue+webpack dev本地调试全局样式引用失效的解决方案
2019/11/12 Javascript
解决vue v-for src 图片路径问题 404
2019/11/12 Javascript
在Docker上部署Python的Flask框架的教程
2015/04/08 Python
Python实现的双色球生成功能示例
2017/12/18 Python
查看Django和flask版本的方法
2018/05/14 Python
flask应用部署到服务器的方法
2019/07/12 Python
利用python实现短信和电话提醒功能的例子
2019/08/08 Python
python实现飞行棋游戏
2020/02/05 Python
HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)
2017/01/05 HTML / CSS
解析HTML5的存储功能和web SQL的相关操作方法
2016/02/19 HTML / CSS
基本款天堂:Everlane
2017/05/13 全球购物
三陽商会官方网站:Sanyo iStore
2019/05/15 全球购物
业绩考核岗位职责
2014/02/01 职场文书
《一件运动衫》教学反思
2014/02/19 职场文书
意外伤害赔偿协议书
2014/09/16 职场文书
安全承诺书格式范本
2015/04/28 职场文书
运动会通讯稿600字
2015/07/20 职场文书
党员公开承诺书2016
2016/03/24 职场文书
十二月早安励志心语大全
2019/12/03 职场文书
Python djanjo之csrf防跨站攻击实验过程
2021/05/14 Python
Python中的xlrd模块使用整理
2021/06/15 Python
详细了解MVC+proxy
2021/07/09 Java/Android
vue项目配置sass及引入外部scss文件
2022/04/14 Vue.js
详解OpenCV曝光融合
2022/04/29 Python
Nginx静态压缩和代码压缩提高访问速度详解
2022/05/30 Servers