Skip to content

[v6.0.0-beta] No longer working with React StrictMode #295

Closed

Description

@Dylan-fa
[Error] InitError: nhsuk-header: Root element (`$root`) already initialised
	reportError (chunk-M2OQI4Y5.js:71)
	defaultOnUncaughtError (react-dom_client.js:6965)
	logUncaughtError (react-dom_client.js:7020)
	runWithFiberInDEV (react-dom_client.js:999)
	(anonymous function) (react-dom_client.js:7048)
	callCallback (react-dom_client.js:5491)
	commitCallbacks (react-dom_client.js:5503)
	runWithFiberInDEV (react-dom_client.js:999)
	commitLayoutEffectOnFiber (react-dom_client.js:9976)
	flushLayoutEffects (react-dom_client.js:12924:146)
	commitRoot (react-dom_client.js:12803)
	commitRootWhenReady (react-dom_client.js:12016)
	performWorkOnRoot (react-dom_client.js:11950)
	performWorkOnRootViaSchedulerTask (react-dom_client.js:13505)
	performWorkUntilDeadline (react-dom_client.js:36)
import { Header } from 'nhsuk-react-components'
import './App.css'

function App() {

  return (
    <>
      <Header logo={{ href: '/' }}>
      </Header>
    </>
  )
}

export default App
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
)
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>test</title>
  </head>
  <body>
    <script>document.body.className += ' js-enabled' + ('noModule' in HTMLScriptElement.prototype ? ' nhsuk-frontend-supported' : '');</script>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

Activity

  1. colinrotherham commented on Oct 21, 2025

    @colinrotherham
    Collaborator

    Would you be able to help look into this @Dylan-fa?

    It means the header useEffect() hook is managing to call new Header() from NHS.UK frontend a second time. I've seen it in development, but that's just because Next.js Fast Refresh can forcibly clear state

    See if you can find a better solution? 🙏

    useEffect(() => {
    if (!('current' in moduleRef) || !moduleRef.current || instance) {
    if (!instance) {
    return;
    }
    // Sync menu open state
    if (menuOpen && !instance.menuIsOpen) {
    instance.openMenu();
    }
    // Sync menu close state
    if (!menuOpen && instance.menuIsOpen) {
    instance.closeMenu();
    }
    return;
    }
    import('nhsuk-frontend')
    .then(({ Header }) => setInstance(new Header(moduleRef.current)))
    .catch(setInstanceError);
    }, [moduleRef, instance, menuOpen]);

  2. colinrotherham commented on Oct 21, 2025

    @colinrotherham
    Collaborator

    It could be the dynamic import() Promise is still resolving between renders?

  3. colinrotherham commented on Oct 21, 2025

    @colinrotherham
    Collaborator

    It was a couple of things:

    • We had no handle on import('nhsuk-frontend') so it ran twice
    • Swapped useState() for useRef() to preserve the HTML element handle between renders

    If you can give #296 a test?

  4. Dylan-fa commented on Oct 24, 2025

    @Dylan-fa
    Author

    It was a couple of things:

    • We had no handle on import('nhsuk-frontend') so it ran twice
    • Swapped useState() for useRef() to preserve the HTML element handle between renders

    If you can give #296 a test?

    Yep I built this PR locally and it fixes the StrictMode issue.

  5. colinrotherham commented on Oct 27, 2025

    @colinrotherham
    Collaborator

    Thanks again. You can give this a try in v6.0.0-beta.3

  6. added this to the v6.0.0 milestone on Oct 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions