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のデバッガでも、子コンポーネントとして表示される