portals
将子组件渲染到父组件以外的地方 | v16 react-dom
在react 组件树中子组件与父组件依旧是父子组件关系;
在DOM树中两个组件没有关系
ReactDOM.createPortal(el,aimDom) el(子组件)|aimDom(目标Dom元素)
简单粗暴的🌰 APP:
<div>
<div id="parentComponent"><Dialog>父组件<Dialog/></div>
</div>

portal作为container组件
createPortal(this.props.children,document.getElementById('root'))
子组件Dialog
<Containder><div className="child">dddd</div></Containder>
将Dialog的Dom元素放在Container内,通过createPortal直接将Dom元素渲染到root元素下
>>>>相当于将parentComponent的子组件传送到了root组件下
数据传递、生命周期、时间冒泡仍然存在于react 组件树中
Demo — 弹窗 学以致用
场景: 点击button显示弹窗confirm,其中弹窗position:absolute
方案一:
button、confirm为App的子组件,button设置confirm的显示/隐藏状态
button 需要将状态传给App组件,然后App组件将状态再传给confirm;如果button在更深的组件内的话会消耗数据传递的成本
方案二:
confirm 在button 内
button的样式会影响到confirm
方案三:portal

- /portal/ToBody (传送门) >>>>> 将子元素渲染至body元素内

- /dialog/confirm (组件) >>>>>> 子元素

通过按钮控制isShowConfirm展示弹窗,使用ToBody将浮窗渲染作为body子元素
<div className="confirm-btn">
<button onClick={confirm}>确定</button>
{isShowConfirm ?
<ToBody>
<Confirm
title="点击确定"
confirmText="我真的点了"
cancelText="不,我没点"
msg="确认您真的点击确定了吗?"
onConfirm={onConfirm}
onCancel={onCancel}/>
</ToBody> : null}
</div>
更多场景: 父组件有overflow、z-index属性,需要跳出父组件的状况