React 16では、Portalという新機能が登場しています。
何ができるのか
Portalは、ReactのDOMノードの一部を、実際のDOMでは別な箇所にマウントできる機能です。使い方としては、
- ポップアップ・モーダルなど、全く別個でDOM上の位置を取りたいもの
- バラバラな位置に入るサブコンポーネントをまとめて管理したい場合
などが考えられます。
使い方
ポータルは、ReactDOM.createPortalから作成します。
ReactDOM.createPortal(コンポーネント, DOMノード[, key])
コンポーネントには、ポータルの中にセットするコンポーネント(単なるJSXでももちろんOK)を書きます。そして、DOMノードとして、そのコンポーネントが実際に描画されるDOMノードを指定します。keyは、他のReactエレメントにつけるkeyと同じもので、大量のポータルを.mapで一括生成する場合などに必要となります。
なお、ReactDOM.createPortalの結果自体も一種のReact DOMであって、他のReactコンポーネントに埋め込んで描画する必要があります。Reactの公式サイトには直接render()の返り値にする例がありますが、特にそれに限られません。
render() {
return (
<div>
{
/* このように、子要素として埋め込むことも可能 */
ReactDOM.createPortal(....)
}
</div>
);
}
便利な点
上に挙げた記事のように、内部からReactDOM.renderを使うことでも、別の位置に出すコンポーネントを制御することは、できなくもないです。ただ、ポータルを使うと、いろいろ便利な点があります。
- ふつうに
render()するだけでいいので、今表示中だったか非表示だったかなどを自前で管理する必要がない - Reactの扱い上は、別な位置にあっても子コンポーネントになる
- コンテキストもそのまま子で使える
- イベントも親コンポーネントへバブリングする
- Reactのデバッガでも、子コンポーネントとして表示される