環境
React:v18.3.1
Tips
- DOM上の別の場所に子要素をレンダリングできる。
- モーダルを表示するための手段としても使えるが、個人的にはshowDialog関数を使った方が良いと思う。(ESCキーにデフォルトで対応してくれるし、可読性考えるとdialogタグはわかりやすい)
- ボタン等のイベントハンドラで実行しても反映されないので、return文の中で実行する必要がある。
上の階層に要素追加とモーダル表示
TestCreatePortal.tsxの内容
import TestCreatePortalChild from './TestCreatePortalChild.tsx';
function TestCreatePortal() {
return (
<>
<div>TestCreatePortal</div>
<div id="portal" />
<TestCreatePortalChild />
</>
);
}
export default TestCreatePortal;
TestCreatePortalChild.tsxの内容
import { createPortal } from 'react-dom';
import { useState } from 'react';
function TestCreatePortalChild() {
const [showPortal, setShowPortal] = useState<boolean>(false);
return (
<>
{/* 親コンポーネントに要素追加。 */}
<div>
<button
type="button"
onClick={() => setShowPortal(true)}
>
setShowPortal(true)
</button>
</div>
<div>
{showPortal
&& createPortal(<p>Created Portal</p>, document.getElementById('portal'))}
</div>
{/* 1番上の階層にモーダルの要素を追加。 */}
<div>
{
createPortal(
<dialog id="dialog">
Dialog
</dialog>,
document.getElementById('root'),
)
}
</div>
{/* モーダルを表示 */}
<div>
<button
type="button"
onClick={() => {
document.getElementById('dialog')?.showModal();
}}
>
showModal
</button>
</div>
</>
);
}
export default TestCreatePortalChild;
結果
Webブラウザで以下を確認する。
- 「setShowPortal(true)」を押下すると、そのボタンの上に「Created Portal」と表示される。
- 「showModal」を押下すると、モーダルが表示される。