pop-layer react different from the previous DOM programming, we know that, in the DOM, the popup event binding on the corresponding node can be, but react, often can only achieve transfer control between father and son, obviously, pop level layer does not conform to this relationship.
Here we need to use React official portals
portals can help us beyond the child node into the parent level place
Note: official documents using the class, I used here is react hook
in react
Pre-knowledge
Hook react
useEffect
is a react life cycle componentDidMount
, componentDidUpdate
as well as componentWillUnMount
combinations of three hook function.
useEffect
There are two parametersuseEffect
The second parameter is an empty array corresponding to thecomponentDidMount
execution time perioduseEffect
The second argument is an array containing the equivalent of some state executed only when this change of stateuseEffect
It returns a function equivalent tocomponentWillUnMount
performing a cycle
Implementation steps
1. First, select the pop-layer insert DOM nodes, and here I refer to the official documentation of the project will be divided into app-root
and model-root
two, I'll pop layer is inserted into the model-root
node
function App(){
return(
<React.Fragment>
<div id={"app-root"}>
<Router/>
</div>
<div id={"model-root"}></div>
</React.Fragment>
)
}
2. To achieve the popup
we follow the official document, Mr. el node into a storage container as our child node, and performReactDOM.createPortal
ReactDOM.createPortal(child, container)
We need our first insert the selected node el DOM node, and then portal elements into the DOM tree, so let's use hook in componentDidMount
the insertion el DOM stage
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;
Like this child element will appear in the DOM hierarchy we want
3. The introduction of our Model in the calling page and define the relevant trigger events, and the way these child node to the parent is no different from traditional values
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;