Portal 提供了一种将子节点渲染到存在于父节点以外的DOM节点的优秀方案;

尽管 portal 可以被放置在 DOM 树中的任何地方,但在任何其他方面,其行为和普通的 React 子节点行为一致。由于 portal 仍存在于 React 树, 且与 DOM 树 中的位置无关,那么无论其子节点是否是 portal,像 context 这样的功能特性都是不变的。

这包含事件冒泡。一个从 portal 内部触发的事件会一直冒泡至包含 React 树*的祖先,即便这些元素并不是 *DOM 树 中的祖先

通俗来讲就是假设父节点app-root 通过 ReactDOM.createPortal 将它的子节点,挂载到它的兄弟节点modal-root上,父节点app-root的Partal组件仍然能狗捕获到该子节点冒泡上来的事件。

下面来实现一个建议的弹窗功能

创建Portal插槽组件MsgConten

import React from 'react';
import ReactDOM from "react-dom"; class Model extends React.Component{ constructor(props) {
super(props);
this.el = document.createElement('div');
this.modelRoot = document.getElementById('model-root');
} componentDidMount(){
     //将插入弹窗的div放入到兄弟节点“model-root”中
this.modelRoot.appendChild(this.el);
}
//清理工作
componentWillUnmount() {
this.modelRoot.removeChild(this.el);
}
render() {
return ReactDOM.createPortal((//将创建好的弹窗插入到创建的div元素中
<MsgWindow closeModel={this.props.closeModel}/>
), this.el);
}
}
//弹窗
function MsgWindow(props) {
return(
<div className={'cover'} style={{background:'grey',width:'200px',height:'200px',margin: '0 auto'}}>
<button onClick={props.closeModel}>关闭</button>
<div style={{color:'#ffffff'}}>
我是app-root的子节点,但被渲染在它的兄弟节点model-root上
</div>
</div>
)
} export default Model;

创建两个兄弟节点app-root和model-root

import React,{Component} from 'react';
import Model from './MsgConten'; class Portals extends Component{ state={
showMsg:false
}; handleMsgWindow(){
this.setState({
showMsg:!this.state.showMsg
})
} render() {
return (
<>
<div id={"app-root"} >
{(this.state.showMsg == true)?<Model isShow={this.state.showMsg} closeModel={this.handleMsgWindow.bind(this)}/>:null}
<button onClick={this.handleMsgWindow.bind(this)}>portals</button>
</div>
<div id={"model-root"}></div>
</>
)
}
} export default Portals;

运行效果如下

react portals 插槽 实现简易弹窗的更多相关文章

  1. react portals

    来源:https://segmentfault.com/a/1190000011668286 Portals是react 16.3 提供的官方解决方案,使得组件可以脱离父组件层级挂载在DOM树的任何位 ...

  2. react 全局公共组件-----动态弹窗 (dialog)

    react 的时候,总是会用到弹窗,并且各种各样的,一般来说,组件层级嵌套之后,就会出现 z-index层级覆盖的问题 这个时候,就需要一个公共的弹出层,然后我们将需要展示的组件,放到弹出层里面 下面 ...

  3. react中使用redux简易案例讲解

    为什么我想要使用redux? 前段时间初步上手了react,最近在使用react的过程中发现对于组件之间通信的需求比较迫切,尤其是在axios异步请求后端数据的时候,这样的需求是特别强烈的!举个例子: ...

  4. 基于React.js网页版弹窗|react pc端自定义对话框组件RLayer

    基于React.js实现PC桌面端自定义弹窗组件RLayer. 前几天有分享一个Vue网页版弹框组件,今天分享一个最新开发的React PC桌面端自定义对话框组件. RLayer 一款基于react. ...

  5. React Native之持久化存储(AsyncStorage、react-native-storage)的使用

    AsyncStorage是一个简单的.异步的.持久化的Key-Value存储系统,它对于App来说是全局性的.这是官网上对它的介绍.可以知道,这个asyncstorage也是以键值对的形式进行存储数据 ...

  6. [React] react-interview-01

    1.render 函数中 return 如果没有使用()会有什么问题? 我们在使用 JSX 语法书写 react 代码时,babel 会将 JSX 语法编译成 js,同时会在每行自动添加分号(:),如 ...

  7. React 系列教程2:编写兰顿蚂蚁演示程序

    简介 最早接触兰顿蚂蚁是在做参数化的时候,那时候只感觉好奇,以为是很复杂的东西.因无意中看到生命游戏的 React 实现,所以希望通过兰顿蚂蚁的例子再学习一下 React. 兰顿蚂蚁的规则非常简单: ...

  8. React 精要面试题讲解(五) 高阶组件真解

    说明与目录 在学习本章内容之前,最好是具备react中'插槽(children)'及'组合与继承' 这两点的知识积累. 详情请参照React 精要面试题讲解(四) 组合与继承不得不说的秘密. 哦不好意 ...

  9. Smobiler实现手机弹窗

    前言 在实际项目中有很多场景需要用到弹窗,如图1 那么这些弹窗在Smobiler中如何实现呢? 正文 Smobiler实现弹窗有两种方式:1.MessageBox.Show 2.ShowDialog和 ...

随机推荐

  1. Mac下持续集成-jenkins设置密码及启动

    什么情况呢,现在想起来重新启动jenkins时发现,一切都要从头开始... 输入原始密码: 提示密码在:/var/root/.jenkins/secrets/initialAdminPassword ...

  2. 关于Java 8新引入语法特性的简要说明

    Java 8在语法上的主要改进就是新增了Lambda Expression以及Method Reference.由于官方网站的介绍稍显罗嗦,而且例子也有些复杂.我这里将提供一些更为浅显.直观的例子来帮 ...

  3. mac下的夜神模拟器链接vscode

    1.找到夜神模拟器,点击右键,查看包内容,找到文件夹下面的macos在点击右键打开终端.输入: adb connect 127.0.0.1:62001 dart和flutter交流群:45289287 ...

  4. Qt编写安防视频监控系统3-通道交换

    一.前言 最开始写通道交换的功能的时候,走了很多弯路,比如最开始用最初级的办法,触发交换的时候,先关闭视频,然后设置新的url重新打开视频,这样处理非常低级而且耗内存还卡还很慢,毕竟重新打开视频都需要 ...

  5. Centos7系统下以RPM方式如何安装mysql-5.7

    检查系统是否装有mariadb rpm -qa | grep mariadb 卸载mariadb 强制卸载mariadb rpm -e --nodeps mariadb-libs-5.5.35-3.e ...

  6. 建立本地yum仓库

    [root@ks-server ~]# cd /etc/yum.repos.d/[root@ks-server yum.repos.d]# ls CentOS-Base.repo CentOS-Med ...

  7. tf.contrib.rnn.LSTMCell 里面参数的意义

    num_units:LSTM cell中的单元数量,即隐藏层神经元数量.use_peepholes:布尔类型,设置为True则能够使用peephole连接cell_clip:可选参数,float类型, ...

  8. ffmpeg学习笔记-编译脚本

    之前已经用他人的编译脚本对ffmpeg进行了成功编译,那么在裁剪ffmpeg的时候需要指定文件,这时候应该怎么编写编译脚本呢?本文目的在于说明ffmpeg编译脚本的编写 首先在ffmpeg的目录下新建 ...

  9. spring中的bean的生命周期

    bean的生命周期:bean的创建 —— 初始化 ——销毁的过程 容器管理bean的生命周期,我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期就会调用我们的方法 在xml配置文件中是在 ...

  10. 编写一个自定义事件类,包含on/off/emit/once方法

    function Event() { this._events = {}; } Event.prototype.on = function(type, fn) { if (!this._events[ ...