Repository: react
Issue: Bug: False positive warning with nested roots: Attempted to synchronously unmount a root while React was already rendering.
Labels: Status: Unconfirmed,Type: Discussion

we get a warning on (legitimate?) use case, if there is a manually added react root inside another parent root
(for example for part of Backbone view that is inserted into parent react component)
on unmount we can see that child root is in commit context, so we cant unmount it

React version: 18.2

## Steps To Reproduce

1. have nested react roots, child is manually added/removed on parent mount/unmount
2. unmount parent root

I have 2 way bindings for backbone.marionette and react
* reactToMarionette
* useMarionetteInReact hook
when root/parent component gets rendered/destroyed React gives this warning

```
Warning: Attempted to synchronously unmount a root while React was already rendering.
React cannot finish unmounting the root until the current render has completed,
which may lead to a race condition.
```
I am looking for ways to fix this warning

I think ReactChild node is somehow marked as `toBeRendered` at the app render, even though I would expect that app.root would not know about nested/inserted MView react root

Link to code example: https://codesandbox.io/s/my-test-adapters-forked-tdbgdb

<details><summary>problematic code </summary>

```jsx
import { View } from "backbone.marionette";
import React, { useCallback, useRef, useState } from "react";

import { createRoot } from "react-dom/client";

export function App() {
  // create a reason to render inner component
  const [isVisible, setVisible] = useState(true);
  const toggle = useCallback(() => setVisible((i) => !i), []);

  console.log("render app", isVisible);
  return (
    <>
      <button onClick={toggle}>{`toggle: ${isVisible}`}</button>
      {isVisible ? <SomeComponent /> : null}
    </>
  );
}

// component that children are controlled from outside (by marionette)
const SomeComponent = () => {
  console.log("render SomeComponent");
  const ref = useMarionetteInReact();
  return <div ref={ref} className="stable-react-div"></div>;
};

// hook, for rendering marionette view
const useMarionetteInReact = () => {
  const viewRef = useRef(null);

  const divRef = useCallback((el) => {
    if (el === null) {
      console.log("MView destroy in useCallback", viewRef.current);
      viewRef.current && viewRef.current.destroy();
    } else {
      console.log("created MView");
      const MView = new reactToMarionette({
        className: "reactToMarionette",
        template: false,
        component: <ReactChild />
      });
      viewRef.current = MView;
      MView.render();
      el.appendChild(MView.el);
    }
  }, []);

  return divRef;
};

class reactToMarionette extends View {
  constructor(options) {
    super(options);
    this.component = options.component;
    this.el.textContent = "I am Marionette";

    console.log("create root", this.el);
    this.divEl = document.createElement("div");
    this.divEl.classList.add("portal-root");
    this.root = createRoot(this.divEl);
    this.el.append(this.divEl);
  }

  render() {
    console.log("MView render");
    this.root.render(this.component);
  }

  onBeforeDestroy() {
    console.log("onBeforeDestroy", this.root);
    if (this.root) {
      // setTimeout(() => this.root.unmount());
      this.root.unmount();
    }
  }
}

const ReactChild = () => {
  console.log("render ReactChild");
  return <div> Hello, I am react child </div>;
};

```
</details>

## The current behavior
warning is displayed

## The expected behavior
no warning ?