Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: Cannot read properties of undefined (reading '_internalRoot') #26495

Closed
3gwebtrain opened this issue Mar 28, 2023 · 3 comments
Closed
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@3gwebtrain
Copy link

I am trying to switch the rendering method according to the env flag. getting an error as:
TypeError: Cannot read properties of undefined (reading '_internalRoot')

here is my conditional rendering code:

import { StrictMode } from "react";
import { createRoot, hydrateRoot } from "react-dom/client";

import App from "./App";

const renderDom = () => {
  const container = document.getElementById("root");
  const renderType = process.env.SSR
    ? hydrateRoot(container).render
    : createRoot(container).render;
  renderType(
    <StrictMode>
      <App />
    </StrictMode>
  );
};

renderDom();

Live Demo

@3gwebtrain 3gwebtrain added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Mar 28, 2023
@tariqule
Copy link

tariqule commented Mar 29, 2023

The error you're seeing suggests that container is undefined, which is causing the error when attempting to access _internalRoot. This could happen if the element with the ID of "root" doesn't exist in the HTML document.

you could try something like this, this would solve your issue

document.addEventListener('DOMContentLoaded', () => {
  renderDom();
});

@arthwood
Copy link

@3gwebtrain see my comment here.

@gaearon
Copy link
Collaborator

gaearon commented May 16, 2023

There are two different issues here.

The first issue is that calling root.render without root as the this context is not supported.

So this won't work:

const render = createRoot(domNode).render
render(<App />)

You should always write it like this:

const root = createRoot(domNode)
root.render(<App />)

The second issue is that createRoot and hydrateRoot have different signatures but you're trying to use them in the same way. That's also incorrect. The second hydrateRoot argument is required but you are missing it and trying to render() later, which is not how it's supposed to be used. Please see the hydrateRoot documentation and examples.

Here is the fixed version of your code:

https://codesandbox.io/s/musing-ully-kyuics?file=/src/index.js

  const container = document.getElementById("root");
  const reactNode = (
    <StrictMode>
      <App />
    </StrictMode>
  );
  let root;
  if (process.env.SSR) {
    root = hydrateRoot(container, reactNode);
  } else {
    root = createRoot(container);
    root.render(reactNode);
  }

Note that hydrateRoot is done in a single step because we're specifying which tree to hydrate it with. It doesn't need an additional render. However, createRoot needs a full render because it's initially empty.

Hope this helps.

@gaearon gaearon closed this as completed May 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

4 participants