欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

react学习之弹出层

程序员文章站 2022-06-28 11:53:06
react的弹出层不同于以往的DOM编程,我们知道,在DOM中,弹出层事件绑定在对应的节点上即可,但是在react中,往往只能实现父子之间的传递控制,显然,弹出层的层级不符合此关系。 在这里我们需要使用React官方的portals portals可以帮助我们将子节点插入到父节点层级之外的地方 注: ......

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

portals可以帮助我们将子节点插入到父节点层级之外的地方
注:官方文档使用的是class,我在这里使用的是
在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>
    )
}

2.实现弹出层
我们按照官方文档,先生成一个节点el作为存放我们子节点的容器,并执行reactdom.createportal

reactdom.createportal(child, container)

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

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并定义相关触发事件,这些与子节点向父节点的方式传值无异

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学习之弹出层