React でコンポーネントを作成すると、通常はコンポーネント ツリー内に存在します。これはほとんど問題ありませんが、コンポーネントの特定の部分をコンポーネント ツリーの外に表示したり、まったく別の場所に表示したい場合があります。
これは、他のすべてのコンポーネントの上にある必要があるモーダル ポップアップ ウィンドウを作成するときの一般的な要件です。
これらをコンポーネント内に作成することもできますが、最終的には他の何よりも優先する必要があり、多くのコンポーネント内にネストすると、 z-index
がそれらが含まれているものを下回るため、問題が発生する可能性があります。
この問題を解決するために、 createPortal
を使用してモーダルを独自のコンポーネントからテンプレートの別の部分にテレポートできます。
これにより、HTML ツリーのベース、 body
タグ内、または別の要素内など、必要な場所にコンポーネントを配置できます。
要素はコンポーネント ツリー内に存在しますが、 createPortal
を使用すると、好きな場所に配置できます。
ポータルがどのように機能するかを示すために、 App.js
ファイル内に次の基本的な React コードがあると考えてください。ここでは、モーダルが他のすべての上に表示されるようにします。そのため、 #modal-container
というdiv
を作成しました。これは最終的に、すべてのモーダルを入れたい場所です。
import logo from './logo.svg'; import './App.css'; import { useState } from 'react' import Modal from './components/Modal.js'; function App() { const [isModalOpen, setIsModalOpen] = useState(false); return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <button onClick={() => setIsModalOpen(!isModalOpen)}> Click to Open Modal </button> <Modal modalState={isModalOpen} onClickEvent={() => setIsModalOpen(!isModalOpen)}> This is Modal Content! </Modal> </header> <div id="modal-container"></div> </div> ); } export default App;
App.js
内に、 Modal
というコンポーネントをインポートしました。これは Modal コンポーネントで、ユーザーがボタンをクリックするたびにポップアップします。
setIsModalOpen()
を使用してisModalOpen
を true に設定すると、モーダルが表示されます。そうしないと消えてしまいます。
また、モーダルが実際に他のすべての上に表示されるようにするための CSS も少しあります。
#modal-container { position: absolute; top: 0; left: 0; width: 100%; z-index: 9999; height: 100%; pointer-events: none; } .modal { position: absolute; top: 200px; background: white; border-radius: 4px; left: calc(50% - 100px); width: 200px; }
ポータルの作成は非常に簡単です。 createPortal()
という関数が 1 つあります。 React で何らかの DOM を返す代わりに、 Portal
を返します。
createPortal()
は 2 つの引数 - 返したい DOM 要素 - この場合はモーダル - と DOM 要素をテレポートしたい DOM 要素を受け入れます。
したがって、すべてのモーダルを#modal-container
に入れたいので、2 番目の引数はdocument.getElementById('modal-container')
です。
import { createPortal } from 'react-dom'; function Modal({modalState, onClickEvent}) { if(!modalState) return null; return ( createPortal( <div className="modal"> <button onClick={onClickEvent}>Close Modal</button> <div className="modal-content">Modal Content goes here</div> </div>, document.getElementById('modal-container') ) ); }; export default Modal;
DOM 要素をmodal-container
にテレポートしましたが、それでも通常の React の子のように動作します。ポータルは引き続き React ツリーに存在するため、要素が存在するコンテキストなどの機能は引き続き同じように機能します。
同じファイルにmodal-container
とModal
がありますが、DOM 要素をテレポートする場所は React コードのどこにでもあることに注意してください。
したがって、DOM 内の任意の場所にある完全に異なるサブコンポーネント、要素、または親にテレポートできます。これは非常に強力で便利です。慎重に使用してください。
App.js
HTML をもう一度見てみましょう。
<!-- .... --> <button onClick={() => setIsModalOpen(!isModalOpen)}> Click to Open Modal </button> <Modal modalState={isModalOpen} onClickEvent={() => setIsModalOpen(!isModalOpen)}> This is Modal Content! </Modal> </header> <div id="modal-container"></div>
これで、 Modal
はヘッダーに配置されますが、ボタンを使用してモーダルを開くたびに#modal-container
に表示されます。
ポータルは React の非常に強力なツールです。これらは、コンポーネントベースのシステムの主な問題を解決するための便利な方法です。特定の要素を他の要素よりも優先して転送します。
そのため、この React ポータルのガイドを楽しんでいただけたでしょうか。 React を学習している場合は、最初に Javascript をマスターすることをお勧めします。これは、完全なJavascript ハンドブックで行うことができます。
すてきな一日を。