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 复合选择器应用的几个例子
Sep 11 Javascript
原生Javascript封装的一个AJAX函数分享
Oct 11 Javascript
基于jQuery实现的图片切换焦点图整理
Dec 07 Javascript
jquery 根据name名获取元素的value值
Feb 27 Javascript
JavaScript实现select添加option
Jul 03 Javascript
PHP抓取HTTPS内容和错误处理的方法
Sep 30 Javascript
jQuery自定义元素右键点击事件(实现案例)
Apr 28 jQuery
javascript+html5+css3自定义提示窗口
Jun 21 Javascript
React利用插件和不用插件实现双向绑定的方法详解
Jul 03 Javascript
Vue-Router模式和钩子的用法
Feb 28 Javascript
node版本管理工具n包使用教程详解
Nov 09 Javascript
JavaScript实现点击图片换背景
Nov 20 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操作xml入门之cdata区段
2015/01/23 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
2017/12/21 PHP
通过 Dom 方法提高 innerHTML 性能
2008/03/26 Javascript
web页面数据展示新想法(json)
2010/06/08 Javascript
javascript 内存回收机制理解
2011/01/17 Javascript
jQuery 操作option的实现代码
2011/03/03 Javascript
深入理解JavaScript作用域和作用域链
2011/10/21 Javascript
js定时器怎么写?就是在特定时间执行某段程序
2013/10/11 Javascript
编写自己的jQuery提示框(Tip)插件
2015/02/05 Javascript
JavaScript中的prototype原型学习指南
2016/05/09 Javascript
JavaScript遍历求解数独问题的主要思路小结
2016/06/12 Javascript
Bootstrap Search Suggest使用例子
2016/12/21 Javascript
Vue.js 2.0窥探之Virtual DOM到底是什么?
2017/02/10 Javascript
浅谈vue的iview列表table render函数设置DOM属性值的方法
2017/09/30 Javascript
vue2.0自定义指令示例代码详解
2019/04/25 Javascript
VSCode使用之Vue工程配置eslint
2019/04/30 Javascript
利用js canvas实现五子棋游戏
2020/10/11 Javascript
python创建和删除目录的方法
2015/04/29 Python
轻松掌握python设计模式之访问者模式
2016/11/18 Python
python实现对csv文件的列的内容读取
2018/07/04 Python
Python tkinter label 更新方法
2018/10/11 Python
python 搭建简单的http server,可直接post文件的实例
2019/01/03 Python
TensorFlow查看输入节点和输出节点名称方式
2020/01/04 Python
使用Python爬虫库BeautifulSoup遍历文档树并对标签进行操作详解
2020/01/25 Python
Python web如何在IIS发布应用过程解析
2020/05/27 Python
python 自动识别并连接串口的实现
2021/01/19 Python
详解快速开发基于 HTML5 网络拓扑图应用
2018/01/08 HTML / CSS
中国综合网上购物商城:苏宁易购
2016/08/09 全球购物
英国领先的独立酒精饮料零售商:DrinkSupermarket
2021/01/13 全球购物
志愿者活动总结
2014/04/28 职场文书
大学三年计划书范文
2014/04/30 职场文书
道德大讲堂实施方案
2014/05/14 职场文书
重大事项社会稳定风险评估方案
2014/06/15 职场文书
2014教师“四风问题”对照检查材料思想汇报
2014/09/16 职场文书
2015质检员个人年终工作总结
2015/10/23 职场文书
2016年社会管理综治宣传月活动总结
2016/03/16 职场文书