ReactDOM.createRoot 🆚 ReactDOM.render

What is ReactDOM.createRoot and how is it different from ReactDOM.render?

React 18 introduces a new root API, so let’s figure it out

👉 Current API

We have to pass the container to render function every time we want to explicitly render.

const c…


This content originally appeared on DEV Community and was authored by Nick | React tinkerer ⚛️

What is ReactDOM.createRoot and how is it different from ReactDOM.render?

React 18 introduces a new root API, so let's figure it out

👉 Current API

We have to pass the container to render function every time we want to explicitly render.

const container = document.querySelector('#root');

// Initial render. Container is explicitly accessed.
ReactDOM.render(<App text="Hello" />, container);

// Subsequent renders. Container is explicitly accessed.
ReactDOM.render(<App text="Hello world!" />, container);

👉 What does ReactDOM.render take?

render function takes three arguments:

  • React element to be rendered
  • DOM element to render in
  • function to be executed after render happens

And returns the same container, but with the rendered component.

/**
* @param element - React element to be rendered
* @param container - DOM element to render in
* @param callback - function to be executed after render happens
* @return container - container with renderned component
*/
function render(element, container, callback) {
  // ...
}

👉 How does ReactDOM.render work under the hood?

ReactDOM.render does a couple of validation checks:

  • whether the container is a suitable node
  • whether the container wasn't previously passed to createRoot

Then it passes all received arguments to legacyRenderSubtreeIntoContainer.

// simplified structure
function render(element, container, callback) {
  if (isValidContainer(element)) {
    throw Error('Target container is not a DOM element.');
  }

  if (isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined) {
    // don't throw an error, but logs it into console
    error('container was previously passed to ReactDOM.createRoot().');
  }

  return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
}

👉 New API

It fixes the issue of passing the container every time we want to explicitly render.

// First, we create a root
const root = ReactDOM.createRoot(document.querySelector('#root'));

// Initial render. Container is implicitly accessed.
root.render(<App name="Hello" />);

// Subsequent renders. Container is implicitly accessed.
root.render(<App name="Hello world!" />);

👉 What does ReactDOM.createRoot take?

createRoot function takes only one mandatory argument - DOM element to render in.
And returns RootType, which has render and unmount methods.

P.S. Also createRoot takes the second RootOptions argument, but we'll examine it in the future.

/**
* @param container - DOM element to render in
* @param options - options, related to hydration
* @return RootType - instance of root
*/
function createRoot(container, options) {
  // ...
}

👉 How does ReactDOM.createRoot work under the hood?

On top of the render function, createRoot:

  • checks whether the container isn't a body element
  • provide a bit more detailed warnings

Then createRoot instance a new ReactDOMRoot object and returns it. No legacyRenderSubtreeIntoContainer at all!

// simplified structure
function createRoot(container, options) {
  if (isValidContainer(element)) {
    throw Error('Target container is not a DOM element.');
  }

  if (container.nodeType === 1 && container.tagName.toUpperCase() === 'BODY') {
    console.error('Creating roots directly with document.body is discouraged');
  }

  if (isContainerMarkedAsRoot(container) {
    if (container._reactRootContainer) {
      console.error('container was previously passed to ReactDOM.render().')
    } else {
      console.error('container has already been passed to createRoot() before.');
    }
  }

  return new ReactDOMRoot(container, options);
}

Now you know the underline difference between old render and new createRoot functions!

Let me know, if you want a further comparison of legacyRenderSubtreeIntoContainer and new ReactDOMRoot.

P.S. Follow me on Twitter for more content like this!


This content originally appeared on DEV Community and was authored by Nick | React tinkerer ⚛️


Print Share Comment Cite Upload Translate Updates
APA

Nick | React tinkerer ⚛️ | Sciencx (2022-02-01T09:56:22+00:00) ReactDOM.createRoot 🆚 ReactDOM.render. Retrieved from https://www.scien.cx/2022/02/01/reactdom-createroot-%f0%9f%86%9a-reactdom-render/

MLA
" » ReactDOM.createRoot 🆚 ReactDOM.render." Nick | React tinkerer ⚛️ | Sciencx - Tuesday February 1, 2022, https://www.scien.cx/2022/02/01/reactdom-createroot-%f0%9f%86%9a-reactdom-render/
HARVARD
Nick | React tinkerer ⚛️ | Sciencx Tuesday February 1, 2022 » ReactDOM.createRoot 🆚 ReactDOM.render., viewed ,<https://www.scien.cx/2022/02/01/reactdom-createroot-%f0%9f%86%9a-reactdom-render/>
VANCOUVER
Nick | React tinkerer ⚛️ | Sciencx - » ReactDOM.createRoot 🆚 ReactDOM.render. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/02/01/reactdom-createroot-%f0%9f%86%9a-reactdom-render/
CHICAGO
" » ReactDOM.createRoot 🆚 ReactDOM.render." Nick | React tinkerer ⚛️ | Sciencx - Accessed . https://www.scien.cx/2022/02/01/reactdom-createroot-%f0%9f%86%9a-reactdom-render/
IEEE
" » ReactDOM.createRoot 🆚 ReactDOM.render." Nick | React tinkerer ⚛️ | Sciencx [Online]. Available: https://www.scien.cx/2022/02/01/reactdom-createroot-%f0%9f%86%9a-reactdom-render/. [Accessed: ]
rf:citation
» ReactDOM.createRoot 🆚 ReactDOM.render | Nick | React tinkerer ⚛️ | Sciencx | https://www.scien.cx/2022/02/01/reactdom-createroot-%f0%9f%86%9a-reactdom-render/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.