Skip to content

Bug: useId not stable on hydration with mid-render state update (React 18) #31653

Closed as not planned
@kognise

Description

@kognise

React version: 18.3.1, 18.0.0

Does not occur in React 19, but we can't use React 19.

Summary

I am fully expecting this to be programmer error, but this behavior deeply puzzles me and I can't find any documented reason for it. If this isn't a bug in React, I would definitely consider it a bug in React documentation :)

As far as I can tell, this code follows all of the rules of hooks and documented invariants:

function App() {
  const _id = useId() // If commented out, no warning.

  const [prevValue, setPrevValue] = useState(false)
  if (prevValue === false) setPrevValue(true) // If commented out, no warning.

  return <Inner />
}

// If this component's body is copied into `App`, no warning.
function Inner() {
  const id = useId() // <---- NOT STABLE!

  return <div id={id} />
}

However, it fails with a hydration mismatch error:

client.js:2427 Warning: Prop `id` did not match. Server: ":R6:" Client: ":R2:" Error Component Stack
    at div (<anonymous>)
    at Inner (client.js:23592:40)
    at App (client.js:23596:41)
    at body (<anonymous>)
    at html (<anonymous>)
    at Html (<anonymous>)

Steps To Reproduce

I created a GitHub repo with a minimal reproduction. Steps to run are in the README: https://github.com/kognise/react-reproduction

Alternately, you should be able to see the same behavior by copying the top code sample into any server-rendered (and hydrated) React app.

The current behavior

React prints the warning Prop `id` did not match. Server: ":R6:" Client: ":R2:".

The expected behavior

I would expect this to just work with no issues.

Modifying the snippet as commented makes the warning go away.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Resolution: StaleAutomatically closed due to inactivityStatus: UnconfirmedA potential issue that we haven't yet confirmed as a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions