如何引用Protals
Portabls是ReactDom中的方法,通过ReactDom.createPortal(child,dom)使用的
child:任何可渲染的 React元素
dom:当前绑定于哪个DOM元素中
Portabls作用
某些情况下,我们想将某些内容独立于父组件,甚至于当前挂在DOM元素中root等。
使用手写dialog模态框示例:
index.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="model"></div>
</body>
</html>
在index.html中加入DOM元素,id取名为model,后期做Portals DOM绑定
model.js 组件,弹窗组件
import { PureComponent } from 'react';
import { createPortal } from 'react-dom';
import propTypes from 'prop-types';
import './index.css';
export default class Model extends PureComponent {
static propTypes={
title:propTypes.string,
width:propTypes.string,
top:propTypes.string,
show:propTypes.bool.isRequired,
closeModel:propTypes.func
}
static defaultProps={
title:'标题',
width:'30%',
top:'15vh',
show:false
}
constructor(props){
super(props)
}
render() {
const { children,title,width,top,show , closeModel }=this.props;
const modelChild=(
<div className={ ` ${show?'active':''} model-container` }>
<div className={ ` ${show?'active':''} h-model` }
style={ {top,width,left:`calc(50% - ${parseFloat(width)/2}%)`} }>
<div className="model-header">
<h2>{ title }</h2>
<i onClick={ closeModel }>x</i>
</div>
<div className="model-aside">{children}</div>
<div className="model-footer">
<button className="btn del">取消</button>
<button className="btn sure">确定</button>
</div>
</div>
</div>
)
return createPortal(
modelChild,
document.getElementById('model')
)
}
}
将props.child抽离出来,放在modelChild重新进行渲染,通过ES6结构语法,将createPortal方法拿出来进行使用。
createPortal第一个参数:
modelChild表示,绑定需要渲染的组件。
createPortal第二个参数:
表示,将组件放入改DOM内部。
DemoBlock.js 组件,内部事件点击渲染Dialog组件
import React, { PureComponent } from 'react'
import './index.css'
import Model from '../Model/index';
export default class DemoBlock extends PureComponent {
constructor(props){
super(props)
this.state={
show:false
}
}
render() {
const { show } = this.state;
return (
<div className="demo-block">
<Model closeModel={ this.closeModel.bind(this) } show={ show }>
{
<p>这是一段段落描述</p>
}
</Model>
<h3>这里是测试模块</h3>
<button onClick={ ()=>this.open(show) }>弹窗测试</button>
</div>
)
}
closeModel(){
console.log('执行了关闭')
this.setState({
show:false
})
}
open(type){
console.log('开始执行')
this.setState({
show:!type
})
}
}
Model组件内部标签,在Model中都可以通过props.children获取到
网友评论