Skip to content

Bug: <style precedence> resources permanently lost when portal container is removed from DOM #36373

@kbravh

Description

@kbravh

When a createPortal container holds <style precedence> elements and is later removed from the DOM, React's hoistableStyles map keeps references to the destroyed <style> nodes and never re-creates them. Any component depending on those styles loses them for the rest of the session, even rendering in a connected tree.

React version: 19.0.0 through 19.2.5, and canary 19.3.0-canary-ad5dfc82-20260427

Steps To Reproduce

  1. Render a component using <style href="x" precedence="custom"> inside a createPortal whose container is a detached div
  2. Render the same component (same href) directly in the main tree
  3. Remove the portal container from the DOM
  4. The directly-rendered component loses its styles and never gets them back

Link to code example: https://stackblitz.com/edit/vitejs-vite-fkhvowjt

The current behavior

React inserts the <style> into the portal container because getRootNode() on a detached element returns itself. When a second instance of the same resource renders in the main tree, React sees the existing hoistableStyles entry and reuses it, but the actual element still lives inside the portal container. Removing that container destroys the <style> node. The map still points to the dead node (isConnected: false, parentNode: DIV), so React never re-creates it. Styles are gone.

The expected behavior

Removing a portal container should not destroy style resources used by components elsewhere in the tree. acquireResource should check whether a cached style instance is still connected and re-create it if not.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status: UnconfirmedA potential issue that we haven't yet confirmed as a bug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions