ポータルは、子要素を DOM 上の別の場所(親の DOM 階層の外)にレンダリングしつつ、React のコンポーネントツリー上では維持します。そのため、context・props・イベントは通常通りネストされているかのように機能します。
jsx
{ createPortal } ;
() {
(
,
.()
);
}
モーダル、ツールチップ、ドロップダウン、トーストは、祖先の overflow: hidden や z-index の重なりコンテキストから脱出する必要があります。もしモーダルが overflow: hidden のカード内に深くネストされていたら、クリップされてしまいます。ポータルで body にレンダリングすれば、これを完全に回避できます。
これは微妙ながら強力な点です。モーダルの DOM が body の下に存在していても、React の祖先に付けた onClick は依然として発火します。なぜなら、イベントのバブリングは DOM ツリーではなく React ツリーに従うからです:
<div onClick={handleParentClick}> {/* still fires for clicks inside the portal */}
<Modal>...</Modal>
</div>
ポータルが解決するのは配置であって、a11y ではありません。ダイアログには依然としてフォーカストラップ、role="dialog"/aria-modal、Escape での閉じる操作が必要です(あるいは、これらの多くを処理してくれるネイティブの <dialog> 要素を使います)。