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. RabbitMQ的三大交换器

    pom文件都是相同的 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...

  2. 第6节:Java基础 - 三大集合(上)

    第6节:Java基础 - 三大集合(上) 本小节是Java基础篇章的第四小节,主要介绍Java中的常用集合知识点,涉及到的内容包括Java中的三大集合的引出,以及HashMap,Hashtable和C ...

  3. HDU4117 GRE WORDS(AC自动机+线段树维护fail树的dfs序)

    Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the mos ...

  4. 联合查询和数据库设计e-r图

    联合查询: 联合查询的关键字是: union 基本含义 联合查询就是将两个select语句的查询结果“层叠”到一起成为一个“大结果”. 两个查询结果的能够进行“联合”的先觉条件是:结果字段数相等. 就 ...

  5. 【Java Web开发学习】Spring MVC整合WebSocket通信

    Spring MVC整合WebSocket通信 目录 ========================================================================= ...

  6. Soc常见问题

    SOC常见问题解答 1.SOC FPGA中的ARM是软核还是硬核?ARM核的外设是软核还是硬核? SOC FPGA 中的ARM核是硬核.所以简称HPS,Hardware Processor Syste ...

  7. C# MD5加密字符串

    /// <summary> /// 用MD5加密字符串,可选择生成16位或者32位的加密字符串 /// </summary> /// <param name=" ...

  8. 《Java基础知识》Java instanceof 运算符

    java多态性带来一个问题,就是如何判断一个变量所实际引用对象的类型.这里java帮我们引入了 instanceof 运算符. instanceof运算符用来判断一个变量的所引用对象的实际类型,注意是 ...

  9. vue-UI(mui和muit-UI)

    MUI和MUIT-UI 这里使用了连个UI---mui和mit-ui mit-ui是基于vue.js的,而mui是一个高性能前端框架(H5+提供的),类似于bootstrap,所以在引入时区别还是很大 ...

  10. SpannableStringBuilder实现图文混排

    1.我的后面添加图片 ssb = new SpannableStringBuilder("我的后面添加图片: "); ssb.setSpan(, , Spannable.SPAN_ ...