Open4

ReactのcreatePortalとは何か

nakaakistnakaakist

基本的には、「DOMの異なる部分にchildrenをrenderする」機能。

普通、Reactでは、createRootの引数に渡されたDOMの中にコンポーネントをrenderしていくが、これを特定の部分だけ別のDOMに変えられる。

例えば、モーダルダイアログとかツールチップなど、親要素のスタイルに影響されたくない、ページの他の部分の上に絶対オーバーレイする系のコンポーネントの描画に向いている。

nakaakistnakaakist

APIの使い方

下記のように、createPortalの第一引数にReactNode、第二引数にDOMノードを入れると、そのDOMノードにrenderしてくれる。

import { createPortal } from 'react-dom';

// ...

<div>
  <p>This child is placed in the parent div.</p>
  {createPortal(
    <p>This child is placed in the document body.</p>,
    document.body
  )}
</div>

ここで、createPortalによってrenderされたJSXは、「そのJSXが普通にReactのtreeの中にある」ように振る舞う。親コンポーネントのcontextにもアクセスできるし、portal内から発生したイベントを親コンポーネントでキャッチもできる。

ただ単にrender先の物理DOMが変わるだけ。

nakaakistnakaakist

ユースケース

  • モーダル、ツールチップ
  • React外のDOMノードにReactコンポーネントを描画する
    • 例えば、非Reactの地図ウィジェットの中にReactでポップアップを出したい、かつ、地図ウィジェットのAPIの中で、「DOMを渡すとpopup描画してくれる」みたいなものがあるとき。
    • まず、document.createElementでDOMを作り、そこに対してcreatePortalでReactのnodeをrenderするとできる。