react学习之弹出层
react的弹出层不同于以往的DOM编程,我们知道,在DOM中,弹出层事件绑定在对应的节点上即可,但是在react中,往往只能实现父子之间的传递控制,显然,弹出层的层级不符合此关系。
在这里我们需要使用React官方的portals
portals可以帮助我们将子节点插入到父节点层级之外的地方
注:官方文档使用的是class,我在这里使用的是react hook
在react
前置知识
react hook
useEffect是了react生命周期中的componentDidMount、componentDidUpdate以及componentWillUnMount三个钩子函数的组合。
useEffect有两个参数useEffect第二个参数为空数组相当于在componentDidMount周期执行一次useEffect第二个参数为含有某种state的数组相当于只有在这个state发生改变的时候才执行useEffect返回一个函数相当于在componentWillUnMount周期执行一次
实现步骤
1.首先,选择要插入弹出层的DOM节点,在这里我参照官方文档将整个项目分成了app-root和model-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学习之弹出层的更多相关文章
- React native 的弹出层(输入)效果
/*弹出层测试*/ import React,{Component} from 'react'; import { StyleSheet, View, Image, Text, TouchableOp ...
- React/anu实现弹出层2
这次是使用了一个比较罕见的APIReactDOM.unstable_renderSubtreeIntoContainer,ReactDOM.unstable_renderSubtreeIntoCont ...
- Layui弹出层详解
今天空了学习一下弹出层 还是一步步展示把 首先,layer可以独立使用,也可以通过Layui模块化使用.我个人一直是用的模块化的 所以下面素有的都是基于模块化的. 引入好相关文件就可以开始啦 今天放 ...
- 利用React/anu编写一个弹出层
本文将一步步介绍如何使用React或anu创建 一个弹出层. React时代,代码都是要经过编译的,我们很多时间都耗在babel与webpack上.因此本文也介绍如何玩webpack与babel. 我 ...
- react 点击空白处隐藏弹出层
点击空白处隐藏弹出层的原理是:在 document 上绑定事件来隐藏弹出层,这样点击任何元素的时候都会冒泡到 document 上,都会执行隐藏弹出层的功能.然后我们在不需要隐藏弹出层的元素上阻止冒泡 ...
- React Portal - 弹出层的优秀解决方案
对于需要使用弹出层的需求 ,Portal可以说是提供了一种完美的解决方案.相比于React Native中的实现更多的使用Modal或者绝对定位,Portal实在是简易友好得多. 场景 对话框,确认提 ...
- JavaScript学习笔记(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例
一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...
- JavaScript学习总结(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例
一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...
- JavaScript学习总结(二)——延迟对象、跨域、模板引擎、弹出层、AJAX示例
一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...
随机推荐
- Windows环境下XAMPP的相关设置
WINDOWS环境下多域名多端口配置:https://www.cnblogs.com/c-and-unity/p/4539348.html
- 数据库Oracle函数之单行函数的介绍
函数介绍: 函数:是数据库产品中提供的能够处理查询结果的方法. 函数能够用于下面的目的: • 执行数据计算 • 修改单个数据项 • 格式化显示的日期和数字 • 转换列数据类型 • 函数有输入参数,并且 ...
- A* 算法讲解
在看下面这篇文章之前,先介绍几个理论知识,有助于理解A*算法. 启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标.这样可以省略大量无 ...
- A.Sweet Problem
题目:甜蜜的问题 题意:你有三堆糖果:红色,绿色,蓝色 第一堆有r个糖果,第二堆有g个糖果,第三堆有b个糖果 每天都可以吃两个不同颜色的糖果,找出可以吃糖果的最大天数 分析:先排下序,如果最大堆大于等 ...
- SpringBoot系列之集成Mybatis教程
SpringBoot系列之集成Mybatis教程 环境准备:IDEA + maven 本博客通过例子的方式,介绍Springboot集成Mybatis的两种方法,一种是通过注解实现,一种是通过xml的 ...
- JAVA可视化闹钟源码
概述 一些同学的Java课设有这样一个问题,比较感兴趣就做了一下 功能介绍: 1.可增加闹钟 2.可删除闹钟 3.时间到了响铃 4.关闭闹钟不会丢失闹钟(因为闹钟存储在txt文件中,不会因程序关闭就终 ...
- 每天用Mybatis,但是Mybatis的工作原理你真的知道吗?
近来想写一个mybatis的分页插件,但是在写插件之前肯定要了解一下mybatis具体的工作原理吧,于是边参考别人的博客,边看源码就开干了. 核心部件: SqlSession Executor Sta ...
- node-sass下载失败
在angular项目中下载依赖npm install时提示node-sass安装失败,解决方法如下: 1.下载win32-x64-57_binding.node文件至指定目录 2.添加环境变量: 变量 ...
- Python复习第01天---元类底层原理
1.通过元类限制类的名字首字母大写 if not class_name.istitle(): raise TypeError('类的名字首字母需要大写') 2. 控制类中必须要有注释 if not c ...
- UWP GraphQL数据查询的实现
1. 缘起 Facebook 的移动应用从 2012 年就开始使用 GraphQL.GraphQL 规范于 2015 年开源,现已经在多种环境下可用,并被各种体量的团队所使用. 在这个链接可以看到更多 ...