背景介紹
想象一下現在有圖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等組件的實現有了很大的幫助