react的弹出层不同于以往的DOM编程,我们知道,在DOM中,弹出层事件绑定在对应的节点上即可,但是在react中,往往只能实现父子之间的传递控制,显然,弹出层的层级不符合此关系。

在这里我们需要使用React官方的portals

portals可以帮助我们将子节点插入到父节点层级之外的地方

注:官方文档使用的是class,我在这里使用的是react hook

在react

前置知识

react hook

useEffect是了react生命周期中的componentDidMountcomponentDidUpdate以及componentWillUnMount三个钩子函数的组合。

  • useEffect有两个参数
  • useEffect第二个参数为空数组相当于在componentDidMount周期执行一次
  • useEffect第二个参数为含有某种state的数组相当于只有在这个state发生改变的时候才执行
  • useEffect返回一个函数相当于在componentWillUnMount周期执行一次

实现步骤

1.首先,选择要插入弹出层的DOM节点,在这里我参照官方文档将整个项目分成了app-rootmodel-root两层,我将把弹出层插入到model-root节点中

function App(){
return(
<React.Fragment>
<div id={"app-root"}>
<Router/> </div> <div id={"model-root"}></div>
</React.Fragment>
)
}
export default App;

2.实现弹出层

我们按照官方文档,先生成一个节点el作为存放我们子节点的容器,并执行ReactDOM.createPortal

ReactDOM.createPortal(child, container)

我们需要先将我们的el节点插入选定的DOM节点,然后再将portal元素插入DOM树中,故我们先用hook在componentDidMount阶段将el插入DOM

(1)首先获取我们要插入的DOM节点id=model-root

 const modelRoot = document.getElementById('model-root');

(2)创建一个存放子节点的元素el

const [el,changEl] = useState(document.createElement('div'));

(3)在componentDidMount阶段将el节点插入model-root

    //初始化工作
useEffect(()=>{ modelRoot.appendChild(el); },[])

(4)渲染组件,执行createPortal方法

    return ReactDOM.createPortal((
<Content closeModel={props.closeModel}/>
), el);

(5)在componentWillUnMount阶段移除我们的el节点

    //清理工作
useEffect(()=>{
return ()=>{
modelRoot.innerHTML=""; }
})

完整代码如下:

import React,{useState,useEffect} from 'react';
import './Model.css';
import ReactDOM from "react-dom";
import ExcelUtil from '../../utils/excelUtil'; function Content(props) {
return(
<div className={'cover'}>
<button onClick={props.closeModel}>关闭</button>
<input type='file' accept='.xlsx, .xls' onChange={(e)=>{ExcelUtil.importExcel(e)} }/> </div>
)
} function Model(props){
const appRoot = document.getElementById('app-root');
const modelRoot = document.getElementById('model-root');
const [el,changEl] = useState(document.createElement('div')); //初始化工作
useEffect(()=>{ modelRoot.appendChild(el); },[])
//清理工作
useEffect(()=>{
return ()=>{
modelRoot.innerHTML=""; }
})
return ReactDOM.createPortal((
<Content closeModel={props.closeModel}/>
), el);
} export default Model;

这样子子元素就出现在了我们想要的DOM层级中

3.在调用页中引入我们的Model并定义相关触发事件,这些与子节点向父节点的方式传值无异

  {(isShowPop == true)?<Model isShow={isShowPop} closeModel={handleInClick}/>:null}

function RegisterInUser() {
const [isShowPop,changeShowPop] = useState(false);
function handleInClick(){
changeShowPop(!isShowPop);
}
return(
<React.Fragment>
//这里是使用的地方
{(isShowPop == true)?<Model isShow={isShowPop} closeModel={handleInClick}/>:null} <button className="ui-button ui-button-primary" onClick={handleInClick}>导入人员</button>
<button
className="ui-button ui-button-primary outExcelBtn"
type="primary"
onClick={() => {ExcelUtil.exportExcel(initColumn, attendanceInfoList,"人员名单.xlsx")}}>
导出表格
</button> </React.Fragment>
)
} export default RegisterInUser;

最终的丑陋效果

react学习之弹出层的更多相关文章

  1. React native 的弹出层(输入)效果

    /*弹出层测试*/ import React,{Component} from 'react'; import { StyleSheet, View, Image, Text, TouchableOp ...

  2. React/anu实现弹出层2

    这次是使用了一个比较罕见的APIReactDOM.unstable_renderSubtreeIntoContainer,ReactDOM.unstable_renderSubtreeIntoCont ...

  3. Layui弹出层详解

    今天空了学习一下弹出层 还是一步步展示把 首先,layer可以独立使用,也可以通过Layui模块化使用.我个人一直是用的模块化的 所以下面素有的都是基于模块化的. 引入好相关文件就可以开始啦  今天放 ...

  4. 利用React/anu编写一个弹出层

    本文将一步步介绍如何使用React或anu创建 一个弹出层. React时代,代码都是要经过编译的,我们很多时间都耗在babel与webpack上.因此本文也介绍如何玩webpack与babel. 我 ...

  5. react 点击空白处隐藏弹出层

    点击空白处隐藏弹出层的原理是:在 document 上绑定事件来隐藏弹出层,这样点击任何元素的时候都会冒泡到 document 上,都会执行隐藏弹出层的功能.然后我们在不需要隐藏弹出层的元素上阻止冒泡 ...

  6. React Portal - 弹出层的优秀解决方案

    对于需要使用弹出层的需求 ,Portal可以说是提供了一种完美的解决方案.相比于React Native中的实现更多的使用Modal或者绝对定位,Portal实在是简易友好得多. 场景 对话框,确认提 ...

  7. JavaScript学习笔记(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例

    一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...

  8. JavaScript学习总结(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例

    一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...

  9. JavaScript学习总结(二)——延迟对象、跨域、模板引擎、弹出层、AJAX示例

    一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...

随机推荐

  1. nmon脚本——对Linux服务器的监控

    继服务器被挖之后,我又开拓了另一个监控工具----nmon! Nmon可以很轻松的监控系统的CPU.内存.网络.硬盘.文件系统.NFS.高耗进程.资源和IBM Power系统的微分区的信息,还有专属的 ...

  2. gsoap使用

    一. 安装gsoap 下载地址:http://sourceforge.net/projects/gsoap2/files/ 解压安装:./configure --prefix=/usr/local/g ...

  3. 压缩感知重构算法之IHT算法python实现

    压缩感知重构算法之OMP算法python实现 压缩感知重构算法之CoSaMP算法python实现 压缩感知重构算法之SP算法python实现 压缩感知重构算法之IHT算法python实现 压缩感知重构 ...

  4. git 设置和取消指定域名代理 - git config proxy

    Firstly - Check Check if U have global .gitconfig file 检查是否有全局 .gitconfig 文件 Usually global .gitconf ...

  5. intellij idea使用tomcat maven plugin

    环境 java 1.8.0_111 tomcat tomcat-8.5.11 maven 3.2.5 intellij idea 14.0.3 命令行使用 建maven工程 mvn archetype ...

  6. 二、Vue 页面渲染过程

    前言 上篇博文我们依葫芦画瓢已经将hello world 展现在界面上啦,但是是不是感觉新虚虚的,总觉得这么多文件,项目怎么就启动起来了呢?怎么访问到8080 端口就能进入到我们的首页呢.整个的流程是 ...

  7. 大数据学习笔记——Hadoop编程之SequenceFile

    SequenceFile(Hadoop序列文件)基础知识与应用 上篇编程实战系列中本人介绍了基本的使用HDFS进行文件读写的方法,这一篇将承接上篇重点整理一下SequenceFile的相关知识及应用 ...

  8. webpack学习3.1由浅入深-打包JS

    打包JS Step1:在新建的文件夹下新建一个sum.js文件,一个app.js文件 sum.js //es module export default function(a,b){ return a ...

  9. C#写入(覆盖形式)数据到CSV文件 和 读取CSV文件

    /// <summary> /// 写入数据到CSV文件,覆盖形式 /// </summary> /// <param name="csvPath"& ...

  10. AQS系列(五)- CountDownLatch的使用及原理

    前言 前面四节学完了AQS最难的两种重入锁应用,下面两节进入实战学习,看看JUC包中其他的工具类是如何运用AQS实现特定功能的.今天一起看一下CountDownLatch. CountDownLatc ...