Skip to content

Latest commit

 

History

History
126 lines (94 loc) · 4.06 KB

File metadata and controls

126 lines (94 loc) · 4.06 KB

Fix: React Hydration Error - Badge in Paragraph

Error

Warning: In HTML, <div> cannot be a descendant of <p>.
This will cause a hydration error.

Problem

The Badge component renders a <div> element, but it was being used inside a <p> tag in the FunctionGraphViewer component. This is invalid HTML because block-level elements (<div>) cannot be nested inside inline elements (<p>).

Invalid HTML Structure:

<p>
  <strong>Change Type:</strong>
  <Badge>  <!-- This renders as <div> -->
    modified
  </Badge>
</p>

This causes React hydration errors because:

  1. The browser automatically closes the <p> tag when it encounters the <div>
  2. React's virtual DOM expects the structure to match the server-rendered HTML
  3. The mismatch causes a hydration error

Location

File: nextjs-frontend/src/components/graph/FunctionGraphViewer.tsx Line: 603-607

Solution

Changed the <p> tag to a <div> tag for the line containing the Badge component.

Before:

<div className="space-y-1 text-sm">
  <p><strong>Name:</strong> {selectedNode.name}</p>
  <p><strong>Type:</strong> {selectedNode.type}</p>
  <p><strong>File:</strong> {selectedNode.filePath}</p>
  <p><strong>Change Type:</strong> 
    <Badge className={`ml-2 ${getNodeColor(selectedNode.changeType)}`}>
      {selectedNode.changeType}
    </Badge>
  </p>
  <p><strong>Similarity:</strong> {(selectedNode.similarity * 100).toFixed(1)}%</p>
</div>

After:

<div className="space-y-1 text-sm">
  <p><strong>Name:</strong> {selectedNode.name}</p>
  <p><strong>Type:</strong> {selectedNode.type}</p>
  <p><strong>File:</strong> {selectedNode.filePath}</p>
  <div><strong>Change Type:</strong> 
    <Badge className={`ml-2 ${getNodeColor(selectedNode.changeType)}`}>
      {selectedNode.changeType}
    </Badge>
  </div>
  <p><strong>Similarity:</strong> {(selectedNode.similarity * 100).toFixed(1)}%</p>
</div>

Why This Works

  • <div> is a block-level element that can contain other block-level elements
  • The Badge component (which renders as <div>) can now be properly nested
  • The visual appearance remains the same (both <p> and <div> are block elements)
  • React hydration now succeeds because the HTML structure is valid

Visual Impact

None - The change is purely structural. The <div> and <p> tags both:

  • Display as block elements
  • Have the same default spacing (controlled by the parent's space-y-1 class)
  • Render identically in the browser

Alternative Solutions Considered

  1. Change Badge to render <span> - Would work, but Badge is semantically a container and <div> is more appropriate
  2. Use <span> wrapper - Adds unnecessary nesting
  3. Change all <p> to <div> - Overkill; only the one with Badge needed changing

Testing

To verify the fix:

  1. Open the application - No hydration error in console
  2. Click on a graph node - Modal opens with function details
  3. Check "Change Type" field - Badge displays correctly
  4. Inspect console - No React warnings or errors

Related Information

HTML Nesting Rules:

  • <p> can only contain phrasing content (inline elements like <span>, <strong>, <em>)
  • <p> cannot contain flow content (block elements like <div>, <section>, <article>)
  • <div> can contain both phrasing and flow content

React Hydration:

  • Server-side rendering generates HTML
  • Client-side React must match that HTML exactly
  • Invalid HTML causes browser to "fix" it, creating mismatches
  • Mismatches trigger hydration errors

Prevention

To avoid similar issues in the future:

  1. Never nest Badge in <p> tags - Badge renders as <div>
  2. Use <div> for complex content - If you need to nest components, use <div>
  3. Use <p> only for simple text - Keep paragraphs for actual paragraph content
  4. Check component implementations - Know what HTML your components render

Files Modified

  • nextjs-frontend/src/components/graph/FunctionGraphViewer.tsx (line 603)

Status

Fixed - Hydration error resolved, no visual changes, valid HTML structure