Skip to content

[BUG] - [V3] Table contains a small amount of data would cause hydration error in server component #6377

@jim-king-2000

Description

@jim-king-2000

HeroUI Version

3.0.1

Describe the bug

A table element with data of more than 4 (rows) x 7 (columns) would lead to hydration error (see error message below).

But it would be OK if:

  1. It contains 3 rows or less.
  2. It contains 6 columns or less.
  3. Add 'use client' into the code.
  4. Use native tags such as table, thead, tr, th, and td.

My env:

  1. Nextjs v16.2.1
  2. Heroui v3.0.1
  3. React v19.2.4
  4. Tailwindcss v4.2.2
  5. Win11

You'll see this error:

Uncaught Error: Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:

- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.

It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.

https://react.dev/link/hydration-mismatch

  ...
    <tbody data-slot="table-body" className="table__body" style={undefined} data-rac="" role="rowgroup" ...>
      <CollectionBranch collection={{keyMap:Map, ...}} parent={{...}} renderDropIndicator={undefined}>
        <Component>
        <Component>
        <Component>
        <Component node={{...}}>
          <TableRowElementType data-slot="table-row" className="table__row" style={undefined} data-rac="" ...>
            <bound $64fa3d84918910a7$var$DOMElement data-slot="table-row" className="table__row" style={undefined} ...>
              <tr data-slot="table-row" className="table__row" style={undefined} data-rac="" role="row" ...>
                <$64fa3d84918910a7$export$2881499e37b75b9a values={[...]}>
                  <CollectionBranch collection={{keyMap:Map, ...}} parent={{...}}>
                    <Component>
                    <Component>
                    <Component>
                    <Component>
                    <Component>
                    <Component>
                    <Component node={{...}}>
                      <TableCellElementType data-slot="table-cell" className="table__cell" style={undefined} data-rac="" ...>
                        <bound $64fa3d84918910a7$var$DOMElement data-slot="table-cell" className="table__cell" ...>
+                         <td
+                           data-slot="table-cell"
+                           className="table__cell"
+                           style={undefined}
+                           data-rac=""
+                           tabIndex={-1}
+                           onFocus={function}
+                           data-collection="react-aria-_R_klrlbH1_"
+                           data-key="react-aria-41"
+                           onDoubleClick={undefined}
+                           onDragStartCapture={function onDragStartCapture}
+                           onClick={undefined}
+                           id="react-aria-_R_7majklrlb_"
+                           role="gridcell"
+                           onKeyDownCapture={function onKeyDownCapture}
+                           aria-colspan={null}
+                           aria-colindex={undefined}
+                           colSpan={null}
+                           onBlur={function}
+                           onPointerEnter={function}
+                           onPointerLeave={function}
+                           data-focused={undefined}
+                           data-focus-visible={undefined}
+                           data-pressed={undefined}
+                           data-selected={undefined}
+                           data-column-index={6}
+                           ref={function}
+                         >

    at throwOnHydrationMismatch (react-dom-client.development.js:5465:11)
    at beginWork (react-dom-client.development.js:12361:17)
    at runWithFiberInDEV (react-dom-client.development.js:986:30)
    at performUnitOfWork (react-dom-client.development.js:18988:22)
    at workLoopConcurrentByScheduler (react-dom-client.development.js:18982:9)
    at renderRootConcurrent (react-dom-client.development.js:18964:15)
    at performWorkOnRoot (react-dom-client.development.js:17822:11)
    at performWorkOnRootViaSchedulerTask (react-dom-client.development.js:20471:7)
    at MessagePort.performWorkUntilDeadline (scheduler.development.js:45:48)

Your Example Website or App

No response

Steps to Reproduce the Bug or Issue

Run this code:

import { Table } from '@heroui/react'

const jobs = Array.from(Array(4).keys())

export default async function Page() {
  return (
    <Table>
      <Table.ScrollContainer>
        <Table.Content aria-label='Team members' className='min-w-[600px]'>
          <Table.Header>
            <Table.Column isRowHeader>1</Table.Column>
            <Table.Column>2</Table.Column>
            <Table.Column>3</Table.Column>
            <Table.Column>4</Table.Column>
            <Table.Column>5</Table.Column>
            <Table.Column>6</Table.Column>
            <Table.Column>7</Table.Column>
          </Table.Header>
          <Table.Body>
            {jobs.map((job) => (
              <Table.Row key={job}>
                <Table.Cell>a</Table.Cell>
                <Table.Cell>a</Table.Cell>
                <Table.Cell>a</Table.Cell>
                <Table.Cell>a</Table.Cell>
                <Table.Cell>a</Table.Cell>
                <Table.Cell>a</Table.Cell>
                <Table.Cell>a</Table.Cell>
              </Table.Row>
            ))}
          </Table.Body>
        </Table.Content>
      </Table.ScrollContainer>
    </Table>
  )
}

Expected behavior

Work well without any error or warning.

Screenshots or Videos

No response

Operating System Version

Win11

Browser

Chrome

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions