From c353dd4fac1ead2381c4fb791b0d3eb296c8bcec Mon Sep 17 00:00:00 2001 From: Jakub Benes Date: Fri, 4 Apr 2025 10:43:46 +0200 Subject: [PATCH 1/4] docs: add note about root.render microtask scheduling --- src/content/reference/react-dom/client/createRoot.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index 0a393394988..9354350bc40 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -90,6 +90,8 @@ React will display `` in the `root`, and take over managing the DOM insid * If you call `render` on the same root more than once, React will update the DOM as necessary to reflect the latest JSX you passed. React will decide which parts of the DOM can be reused and which need to be recreated by ["matching it up"](/learn/preserving-and-resetting-state) with the previously rendered tree. Calling `render` on the same root again is similar to calling the [`set` function](/reference/react/useState#setstate) on the root component: React avoids unnecessary DOM updates. +* Although rendering is synchronous once it starts, calling `root.render(...)` schedules the render in a microtask. This means code after `root.render()` will run before any effects (`useLayoutEffect`, `useEffect`) are fired. This behavior is usually fine and rarely needs adjustment. However, in rare cases where effect timing matters, you can wrap `root.render(...)` in [`flushSync`](https://react.dev/reference/react-dom/client/flushSync) to ensure everything runs synchronously. + --- ### `root.unmount()` {/*root-unmount*/} From 1915036674b8cfbc5b8b8aa7a3cc117f3f83924b Mon Sep 17 00:00:00 2001 From: Jakub Benes Date: Fri, 4 Apr 2025 14:02:55 +0200 Subject: [PATCH 2/4] explicitly mention intial render --- src/content/reference/react-dom/client/createRoot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index 9354350bc40..a793d344ce6 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -90,7 +90,7 @@ React will display `` in the `root`, and take over managing the DOM insid * If you call `render` on the same root more than once, React will update the DOM as necessary to reflect the latest JSX you passed. React will decide which parts of the DOM can be reused and which need to be recreated by ["matching it up"](/learn/preserving-and-resetting-state) with the previously rendered tree. Calling `render` on the same root again is similar to calling the [`set` function](/reference/react/useState#setstate) on the root component: React avoids unnecessary DOM updates. -* Although rendering is synchronous once it starts, calling `root.render(...)` schedules the render in a microtask. This means code after `root.render()` will run before any effects (`useLayoutEffect`, `useEffect`) are fired. This behavior is usually fine and rarely needs adjustment. However, in rare cases where effect timing matters, you can wrap `root.render(...)` in [`flushSync`](https://react.dev/reference/react-dom/client/flushSync) to ensure everything runs synchronously. +* Although rendering is synchronous once it starts, calling `root.render(...)` schedules the render in a microtask. This means code after `root.render()` will run before any effects (`useLayoutEffect`, `useEffect`) are fired. This is usually fine and rarely needs adjustment. In rare cases where effect timing matters, you can wrap `root.render(...)` in [`flushSync`](https://react.dev/reference/react-dom/client/flushSync) to ensure the initial render runs fully synchronously. --- From 125614a0bc0f83c1d8f28ed66eeff30fa805d478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Bene=C5=A1?= Date: Mon, 7 Apr 2025 14:02:04 +0200 Subject: [PATCH 3/4] Update src/content/reference/react-dom/client/createRoot.md Co-authored-by: Sebastian "Sebbie" Silbermann --- src/content/reference/react-dom/client/createRoot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index a793d344ce6..0a1a030ef6d 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -90,7 +90,7 @@ React will display `` in the `root`, and take over managing the DOM insid * If you call `render` on the same root more than once, React will update the DOM as necessary to reflect the latest JSX you passed. React will decide which parts of the DOM can be reused and which need to be recreated by ["matching it up"](/learn/preserving-and-resetting-state) with the previously rendered tree. Calling `render` on the same root again is similar to calling the [`set` function](/reference/react/useState#setstate) on the root component: React avoids unnecessary DOM updates. -* Although rendering is synchronous once it starts, calling `root.render(...)` schedules the render in a microtask. This means code after `root.render()` will run before any effects (`useLayoutEffect`, `useEffect`) are fired. This is usually fine and rarely needs adjustment. In rare cases where effect timing matters, you can wrap `root.render(...)` in [`flushSync`](https://react.dev/reference/react-dom/client/flushSync) to ensure the initial render runs fully synchronously. +* Although rendering is synchronous once it starts, `root.render(...)` is not. This means code after `root.render()` may run before any effects (`useLayoutEffect`, `useEffect`) of that specific render are fired. This is usually fine and rarely needs adjustment. In rare cases where effect timing matters, you can wrap `root.render(...)` in [`flushSync`](https://react.dev/reference/react-dom/client/flushSync) to ensure the initial render runs fully synchronously. --- From eca7e29e5b37971a4aa8f8d210f8be6b8ddbfb41 Mon Sep 17 00:00:00 2001 From: Jakub Benes Date: Mon, 7 Apr 2025 14:10:24 +0200 Subject: [PATCH 4/4] added example --- src/content/reference/react-dom/client/createRoot.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index 0a1a030ef6d..adc6a8d37a7 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -91,6 +91,13 @@ React will display `` in the `root`, and take over managing the DOM insid * If you call `render` on the same root more than once, React will update the DOM as necessary to reflect the latest JSX you passed. React will decide which parts of the DOM can be reused and which need to be recreated by ["matching it up"](/learn/preserving-and-resetting-state) with the previously rendered tree. Calling `render` on the same root again is similar to calling the [`set` function](/reference/react/useState#setstate) on the root component: React avoids unnecessary DOM updates. * Although rendering is synchronous once it starts, `root.render(...)` is not. This means code after `root.render()` may run before any effects (`useLayoutEffect`, `useEffect`) of that specific render are fired. This is usually fine and rarely needs adjustment. In rare cases where effect timing matters, you can wrap `root.render(...)` in [`flushSync`](https://react.dev/reference/react-dom/client/flushSync) to ensure the initial render runs fully synchronously. + + ```js + const root = createRoot(document.getElementById('root')); + root.render(); + // 🚩 The HTML will not include the rendered yet: + console.log(document.body.innerHTML); + ``` ---