ReactのPortalについて
子要素を親要素の階層外にレンダリングすることを可能とする仕組み。
ユースケースとしては、親要素が overflow: hidden や z-index のスタイルを持っていても、子要素は影響を受けることなく独立して表示可能とする(ex. ダイアログ、ツールチップなど)。
完成形のプロジェクト ※公式サンプルをHooksAPIで実装
1. バージョン情報
$ node -v
v12.15.0
$ yarn -v
1.22.4
$ npx create-react-app --version
4.0.3
2. 開発環境の構築
npx create-react-app [プロジェクト名] --template typescript
3. ファイル構成
srcディレクトリ配下で、必要な部分のみ抜粋。
src
├── App.tsx
├── Modal.tsx
4. Portalを実装したModalコンポーネント
Modal.tsx
import React from 'react'
import ReactDOM from 'react-dom'
const Modal: React.FC = ({
children,
}) => {
return (
ReactDOM.createPortal(
children,
document.getElementById('root') as Element
)
)
}
export default Modal
5. 親要素となるAppコンポーネント
App.tsx
import React, { useState } from 'react'
import Modal from './Modal'
import './App.css'
function App() {
const [clicks, setClicks] = useState(0)
const handleClick = () => {
setClicks(clicks + 1)
}
return (
<div className='parent' onClick={handleClick}>
<p>Number of clicks: {clicks}</p>
<p>
Open up the browser DevTools
to observe that the button
is not a child of the div
with the onClick handler.
</p>
<Modal>
<div>
<button>Click</button>
</div>
</Modal>
</div>
)
}
export default App
6. 親要素となるAppコンポーネント
childクラスを持つ要素は、parentクラスを持つ要素の配下ではなく独立して描画される