こんばんは。
今日は「Reactで createPortalを使用したモーダルを作成する方法」について説明いたします。
React で createPortal を使用したモーダルを作成する方法は、React のポータル機能を使って、コンポーネントを DOM の別の場所にレンダリングするものです。モーダルは通常、アプリケーションのルート DOM に直接挿入され、通常のコンテンツとは分離されている必要があるため、このようなポータルを使うのが便利です。
以下は、createPortal を用いたシンプルなモーダルの実装例です。
基本的なModalコンポーネント
Modal.js というコンポーネントを作成し、ポータルを使ってモーダルを別の DOM ノードにレンダリングします。
// Modal.js
import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import './Modal.css'; // スタイリング用のCSSファイル
const Modal = ({ isOpen, onClose, children }) => {
// モーダルが開いていない場合は何も表示しない
if (!isOpen) return null;
// モーダルの外をクリックした時に閉じる処理
const handleClickOutside = (e) => {
if (e.target.className === 'modal-overlay') {
onClose();
}
};
// useEffectでエスケープキーを押した時にモーダルを閉じる
useEffect(() => {
const handleEsc = (e) => {
if (e.key === 'Escape') {
onClose();
}
};
window.addEventListener('keydown', handleEsc);
return () => window.removeEventListener('keydown', handleEsc);
}, [onClose]);
// ポータルを利用してbodyに直接モーダルを描画する
return ReactDOM.createPortal(
<div className="modal-overlay" onClick={handleClickOutside}>
<div className="modal-content">
<button className="modal-close" onClick={onClose}>
Close
</button>
{children}
</div>
</div>,
document.getElementById('modal-root') // モーダルを表示するためのDOMノード
);
};
export default Modal;
モーダル用のスタイリング
次に、Modal.css というCSSファイルを作成し、モーダルのスタイルを定義します。
/* Modal.css */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content {
background-color: white;
padding: 20px;
border-radius: 8px;
max-width: 500px;
width: 100%;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
z-index: 1001;
position: relative;
}
.modal-close {
position: absolute;
top: 10px;
right: 10px;
background: none;
border: none;
font-size: 16px;
cursor: pointer;
}
モーダルを使用する親コンポーネント
App.js にて、モーダルの状態管理と使用方法を記述します。
// App.js
import React, { useState } from 'react';
import Modal from './Modal';
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false);
return (
<div className="App">
<h1>React Modal with Portal</h1>
<button onClick={openModal}>Open Modal</button>
<Modal isOpen={isModalOpen} onClose={closeModal}>
<h2>This is a Modal</h2>
<p>Click outside or press Esc to close.</p>
</Modal>
</div>
);
}
export default App;
index.html でモーダル用のノードを追加
React アプリケーションの public/index.html にモーダル用の DOM ノードを追加します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Modal with Portal</title>
</head>
<body>
<div id="root"></div>
<div id="modal-root"></div> <!-- モーダル用のポータルルート -->
</body>
</html>
動作確認
- 「Open Modal」ボタンをクリックすると、モーダルが表示されます。
- モーダルの外側をクリックするか、エスケープキーを押すとモーダルが閉じます。
この方法で、createPortal を使って React アプリケーションにモーダルを実装することができます。ポータルを使うことで、モーダルが通常の DOM ツリーの構造に影響を与えずに表示されます。
今日は以上です。
ありがとうございました。
よろしくお願いいたします。