ReactのvalidateDOMNestingエラーの修正:<p>の中に<div>を入れないでください

初級者⚛️ React2026-04-24| React 16.8+, Next.js (クライアントサイドレンダリング), Chrome デベロッパーツール

Error Message

Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>. See ... > p > div.
#react#dom#html#ネスト#validateDOMNesting#セマンティックHTML

コンソールの警告画面上は完璧に見えていても、Chromeのデベロッパーツールを開くと大量の警告が表示されることがあります。その中でも頻繁に見られるのが validateDOMNesting エラーです。通常、以下のようなメッセージで突然現れます。

Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>. 
See App > Layout > p > div.

アプリがクラッシュすることはありませんが、HTMLの基本ルールに違反しています。Reactは本質的に競合を指摘しています。ブラウザは段落(pタグ)の中にブロックレベル要素を配置することを許可していません。これを無視すると、ハイドレーションエラーや予期しないUIの崩れ(UI shifts)が発生し、ユーザーを困惑させる原因になります。

実際に何が起きているのかHTML5の仕様では、<p> 要素はテキストのコンテナとして定義されています。これには「フレーズ・コンテンツ(phrasing content)」、つまり <span><strong><em> などしか含めることができません。対照的に、<div> はブロックレベルの「フロー・コンテンツ(flow content)」です。ブラウザが <p> の中に <div> を見つけると、単に表示するだけでなく、<div> が始まる直前で段落を強制的に閉じます。これにより、Reactの仮想DOMとブラウザの実際の構造との間に不一致が生じます。

バグが発生する例このスニペットは、確実に警告を発生させる例です。

const MyComponent = () => {
  return (
    <p>
      情報をチェックしてください:
      <div>ここにブロックレベルのコンテンツが入ります</div>
    </p>
  );
};

なぜこのエラーが発生するのか- ライブラリのデフォルト設定: Material UI (MUI) などのUIキットでは、Typography コンポーネントがデフォルトで <p> としてレンダリングされることがよくあります。その中にリストやボックスをネストすると、警告が表示されます。- 動的な状態: ステータスメッセージや複雑なアイコンのラッパーを条件付きで表示する段落があるかもしれません。- CMSコンテンツ: dangerouslySetInnerHTML を使用して古いデータを挿入すると、単なるテキストだと思っていたコンテナの中に <div> が紛れ込むことがよくあります。## 手っ取り早い修正:コンテナを変更する最も速い解決策が最善である場合も多いです。SEOのためにどうしても段落が必要というわけでなければ、外側の <p><div><section> に入れ替えましょう。これにより、即座にHTML標準に準拠したコードになります。

// 汎用的なコンテナを使用して修正
const MyComponent = () => {
  return (
    <div>
      情報をチェックしてください:
      <div>ここにブロックレベルのコンテンツが入ります</div>
    </div>
  );
};

セマンティックな修正:Spanに切り替えるスタイリングのためにどうしても段落タグが必要な場合もあります。その場合は <p> を維持しつつ、すべての子要素がインライン要素であることを確認してください。内部の <div><span> に置き換え、ブロックのような見た目を維持する必要がある場合はCSSで display: block を適用します。

// ブロック形式のspanを使用した有効なHTMLネスト
const MyComponent = () => {
  return (
    <p>
      情報をチェックしてください:
      <span style={{ display: 'block' }}>
        これで有効な形式になり、警告は発生しません
      </span>
    </p>
  );
};

Next.jsとハイドレーションの悪夢Next.jsのようなSSRフレームワークでは、このエラーは特に危険です。サーバー側での初回レンダリング時、Reactは divp の中にある文字列を生成します。しかし、そのHTMLがブラウザに到達した瞬間、ブラウザはそれを「修正」します。クライアント側でReactが処理を引き継ごうとしたとき、ブラウザ側のDOM構造が送信されたものと一致しません。これが恐ろしい「ハイドレーション不一致(Hydration Mismatch)」を引き起こし、読み込みの遅延や、不一致を解消しようとする際のごく短い表示の崩れ(レイアウトジャンプ)の原因となります。

確認チェックリスト- ファイルを保存し、HMR(Hot Module Replacement)でページを更新します。- F12 キーを押してコンソールを開き、ハードリフレッシュを実行します。- validateDOMNesting 警告が消えたことを確認します。- 要素を右クリックして「検証」を選択します。ブラウザがコンテンツの周囲にゴースト閉じタグ(</p><p>)を勝手に挿入していないか確認してください。### クイックリファレンス:有効なネスト- <p> 許可される要素: <span>, <a>, <button>, <strong>, <br>.- <p> 禁止される要素: <div>, <h1-h6>, <ul>, <section>, <p>.

Related Error Notes