0Pricing
React Academy · レッスン

Portalsでモーダルコンポーネントを構築する

createPortalを使い、document.bodyにレンダリングする再利用可能なモーダルを作成します

「Portalsでモーダルコンポーネントを構築する」はCoddyKit上の無料React Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。

ようこそ

このレッスンでは、React.createPortalを使ってdocument.bodyにレンダリングする再利用可能なModalコンポーネントを構築します。背景のクリックとEscapeキーによる閉じる操作にも対応します。

Modalコンポーネントの基本構造

まず基本構造から始めます。`isOpen`、`onClose`、`children` propsを受け取るModalコンポーネントを作成してください。`isOpen`がfalseの場合は何もレンダリングしません。
function Modal({ isOpen, onClose, children }) {
  if (!isOpen) return null;
  return createPortal(
    <div className="backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        {children}
      </div>
    </div>,
    document.body
  );
}

背景とイベント伝播の停止

外側の`backdrop` divで画面全体を覆います。これをクリックすると`onClose`が呼び出されます。内側の`modal` divでは`e.stopPropagation()`を呼び出し、モーダル内のクリックが背景までバブリングして誤って閉じないようにします。

Escapeキーで閉じる

`keydown`イベントを監視する`useEffect`を追加してください。モーダルが開いている状態でEscapeキーが押されたら、`onClose`を呼び出します。クリーンアップ時にリスナーを削除してください。
useEffect(() => {
  if (!isOpen) return;
  const handle = (e) => { if (e.key === 'Escape') onClose(); };
  document.addEventListener('keydown', handle);
  return () => document.removeEventListener('keydown', handle);
}, [isOpen, onClose]);

bodyのスクロールを防止する

モーダルが開いている間は、通常、その背後にあるページをスクロールできないようにします。`useEffect`内で`document.body`に`overflow: hidden`を設定し、不要になったら削除してください。
useEffect(() => {
  if (isOpen) {
    document.body.style.overflow = 'hidden';
  }
  return () => { document.body.style.overflow = ''; };
}, [isOpen]);

モーダルの基本CSS

背景は画面全体を覆う固定オーバーレイにします。モーダルボックスは中央に配置します。最小限のCSSでは、背景にflexboxを使用してモーダルを中央揃えにできます。
.backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.5);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
}
.modal {
  background: white;
  border-radius: 8px;
  padding: 24px;
  min-width: 320px;
}

モーダルを使う

親コンポーネントのboolean型state変数でモーダルを制御してください。Modalに`isOpen`と`onClose` propsを渡します。任意のコンテンツはchildrenとして配置します。
function App() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button onClick={() => setOpen(true)}>Open Modal</button>
      <Modal isOpen={open} onClose={() => setOpen(false)}>
        <h2>Hello from the modal!</h2>
        <button onClick={() => setOpen(false)}>Close</button>
      </Modal>
    </>
  );
}

内部に閉じるボタンを追加する

キーボードを使えないユーザーや背景に気付かないユーザーのために、モーダル内には必ず明示的な閉じるボタンを用意してください。childrenまたはpropを介して、`onClose`をコンテンツに渡します。

CSSトランジションによるアニメーション

フェードイン効果を追加するには、閉じたときにnullを返すのではなく、Portalを常にレンダリングしてCSSクラスを切り替えます。背景にCSSの`opacity`と`transform`のトランジションを使用してください。
// Toggle class based on isOpen
<div className={`backdrop ${isOpen ? 'visible' : 'hidden'}`}>

モーダルのヘッダーとフッターを組み合わせる

モーダルを`Modal.Header`、`Modal.Body`、`Modal.Footer`のサブコンポーネントに分割してください。複合コンポーネントパターンを使うと、利用者はクラス名を知らなくてもモーダルのレイアウトを組み合わせられます。

確認問題

内側のmodal divのonClickハンドラーで、なぜe.stopPropagation()を呼び出すのですか?

まとめ

createPortalを使ってModalを構築しました。背景のクリックで閉じ、Escapeキーでも閉じ、開いている間はbodyのスクロールをロックします。また、stopPropagationによってモーダル内部のクリックで閉じないようにしました。

次のレッスン

次のレッスン: **モーダルのフォーカスとキーボードトラップの処理** — アクセシビリティ要件を満たすため、モーダルが開いている間はフォーカスをモーダル内に保持します。

よくある質問

「Portalsでモーダルコンポーネントを構築する」レッスンは無料ですか?

はい。「Portalsでモーダルコンポーネントを構築する」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。

「Portalsでモーダルコンポーネントを構築する」で何を学びますか?

createPortalを使い、document.bodyにレンダリングする再利用可能なモーダルを作成します ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

React Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Portalsでモーダルコンポーネントを構築する」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このReact Academyレッスンでコードを書いて実行できますか?

はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. React Portalsとは?
  2. Portalsでモーダルコンポーネントを構築する
  3. モーダルのフォーカスとキーボードトラップを扱う
  4. Portalsでツールチップとドロップダウンメニューを作る
← React Academyに戻る