React の createPortal 機能を使ってみた

React

背景

ある実装で1画面で2箇所レンダリングを行っている箇所がありました。
(画面の一部のみ React で実装)
具体的に説明すると以下のようなイメージです。

  • HTML
    • ヘッダー
    • ボディ
      • 要素1:レンダリング
      • 要素2
      • 要素3:レンダリング
    • フッター

ボディの中の要素1、3だけ別々でレンダリングされている状態です。

これ2箇所でレンダリングしてるけど1回にした方がいいんでない?と知人にアドバイスもらったので、そんな方法あるのか!と調べ対応しました。

どう対応したの?

React に「createPortal」という機能があるようでこれを使いました。

使い方

実際イメージのコードを載せます

document.addEventListener('DOMContentLoaded', () => {
  const container = document.getElementById('app')
  const root = createRoot(container)

  root.render(<Portal />)
})

const Portal = () => {
  const 要素1Container = document.getElementById('要素1_ID')
  const 要素3Container = document.getElementById('要素3_ID')

  return (
    <StrictMode>
      {createPortal(<要素1 />,要素1Container)}
      {createPortal(<要素3 />, 要素3Container)}
    </StrictMode>
  )
}

ここでは id が app の 要素を取得し createRoot でReactルートを作成、作成したルートに対して Portal コンポーネントをレンダリングしています。
※これは推測ですが、挙動を見る限り作成するルートの場所は同じ画面上であればどこでも問題かと思います。

Portal コンポーネントでは特定の場所に要素1、要素3のコンポーネントを表示するように記述しています。

こうすることで要素1、要素3(子要素)を1回のレンダリングで特定の場所に表示することができるようになりました。
(間に要素2があっても問題ありません)

まとめ

指摘されないとこういう機能がある、とかそもそもレンダリングを1回にまとめよう、という発想が出てこなかったりするのでありがたいですね。

今後も知識を身につけつつ、自分自身もこうしたら良いよ、とアドバイスできるように成長してきたいです。

コメント

タイトルとURLをコピーしました