Skip to content

Add HMR Support for Compound Component Pattern #493

@Newbie012

Description

@Newbie012

Related plugins

Description

When exporting components as a compound object (e.g. export const Accordion = { Root, Item }), React Fast Refresh treats the module as “impure” and falls back to a full reload instead of hot‐swapping the individual subcomponents.

// src/Accordion.tsx
import React from 'react'

const Root: React.FC = () => <div>Accordion Root</div>
const Item: React.FC = () => <div>Accordion Item</div>

export const Accordion = { Root, Item }
// → Editing `Root` or `Item` causes a full reload rather than HMR

Suggested solution

Modify the Fast Refresh logic so that any top‐level export const X = { A, B, … } is inspected. If all properties (A, B, …) refer to PascalCase functions or classes defined in the same file (i.e. valid React components), treat them as HMR boundaries instead of marking the module as impure.

Alternative

  1. Barrel export in the same package

    // src/components/accordion/components.tsx
    import React from 'react'
    export const Root: React.FC = () => <div>Accordion Root</div>
    export const Item: React.FC = () => <div>Accordion Item</div>
    
    // src/components/accordion/index.ts
    export * as Accordion from './components'
  • Trade-off: Explicitly re‐exports Root and Item to enable HMR, but adds extra named exports that clutter IntelliSense.
  1. Separate “micro” package for subcomponents
// packages/accordion/src/components.tsx
import React from 'react'
export const Root: React.FC = () => <div>Accordion Root</div>
export const Item: React.FC = () => <div>Accordion Item</div>

// packages/accordion/src/index.tsx
export * as Accordion from './components'

// apps/app/src/index.tsx
import { Accordion } from "@org/accordion"

return (
   <Accordion.Root>
      <Accordion.Item>...</Accordion.Item>
   </Accordion.Root>
)
  • Trade-off: While intellisense won't suggested slot components anymore, micro-frontends are not for everyone and they introduce an additional complexity

Additional context

Compound components (e.g. <Accordion.Root>, <Accordion.Item>) are a common pattern in UI libraries. Being forced to do a full page reload instead of hot‐swapping slows down development. Enabling HMR for a single object export when all children are valid React components would significantly improve developer experience.

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions