背景介绍
想象一下现在有图1所示的组件结构,并且D组件是相对于A组件定位的。通常有两种解决方式:
图1
1.css定位解决:将D的positon设为absolute,同时将A设为relative。这种方式简单粗暴,但是如果需求有变化,需要将B的positon也设为absolute,那D就不能相对于A节点定位了
2.将组件结构替换成图2所示,直接将D组件当成A组件的组件。这种方式需要通过A组件来维护B组件与D组件的通信,不方便维护
图2
针对这种场景,react16提供了Portals来解决这个问题
Portals
官方给出的定义是:
Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
很多人将它理解成传送门。其用法很简单,下述代码就是实现了上述场景,实际上是图1的结构,但最终渲染成图2的结构
<A>
<B>
<D/>
</B>
<C/>
</A>
// D 组件
import { createPortal } from 'react-dom';
export default class Toast extends React.Component {
constructor() {
super();
}
componentDidMount() {
// 获取A组件内的dom节点
this.dom = document.querySelector('#portals');
}
render() {
return createPortal((
<h3>我是D组件</h3>
), this.dom);
}
}
这样D组件还是B组件的子组件,B组件就可以通过自身来对D组件进行管理
Portals对于Modals、Toast、Tooltips等组件的实现有了很大的帮助