Repository: facebook/react
Pull request: Convert ReactMountDestruction (partially) to createRoot

Two tests make no more sense with the new createRoot API since unmounting is always bound to the root instance. These can be removed in the same PR we also remove `render` and `unmountComponentAtNode`.

Changed files:
filename: packages/react-dom/src/__tests__/ReactDOMRoot-test.js
patch: @@ -133,6 +133,13 @@ describe('ReactDOMRoot', () => {
     expect(container.textContent).toEqual('');
   });
 
+  it('can be immediately unmounted', async () => {
+    const root = ReactDOMClient.createRoot(container);
+    await act(() => {
+      root.unmount();
+    });
+  });
+
   it('supports hydration', async () => {
     const markup = await new Promise(resolve =>
       resolve(
@@ -392,6 +399,18 @@ describe('ReactDOMRoot', () => {
     }
   });
 
+  it('throws if unmounting a root that has had its contents removed', async () => {
+    const root = ReactDOMClient.createRoot(container);
+    await act(() => {
+      root.render(<div>Hi</div>);
+    });
+    container.innerHTML = '';
+
+    expect(() => {
+      root.unmount();
+    }).toThrow('The node to be removed is not a child of this node.');
+  });
+
   it('opts-in to concurrent default updates', async () => {
     const root = ReactDOMClient.createRoot(container, {
       unstable_concurrentUpdatesByDefault: true,

filename: packages/react-dom/src/__tests__/ReactMountDestruction-test.js
patch: @@ -11,31 +11,42 @@
 
 const React = require('react');
 const ReactDOM = require('react-dom');
+const ReactDOMClient = require('react-dom/client');
+const act = require('internal-test-utils').act;
 
 describe('ReactMount', () => {
-  it('should destroy a react root upon request', () => {
+  it('should destroy a react root upon request', async () => {
     const mainContainerDiv = document.createElement('div');
     document.body.appendChild(mainContainerDiv);
 
     const instanceOne = <div className="firstReactDiv" />;
     const firstRootDiv = document.createElement('div');
     mainContainerDiv.appendChild(firstRootDiv);
-    ReactDOM.render(instanceOne, firstRootDiv);
+    const firstRoot = ReactDOMClient.createRoot(firstRootDiv);
+    await act(() => {
+      firstRoot.render(instanceOne);
+    });
 
     const instanceTwo = <div className="secondReactDiv" />;
     const secondRootDiv = document.createElement('div');
     mainContainerDiv.appendChild(secondRootDiv);
-    ReactDOM.render(instanceTwo, secondRootDiv);
+    const secondRoot = ReactDOMClient.createRoot(secondRootDiv);
+    await act(() => {
+      secondRoot.render(instanceTwo);
+    });
 
     // Test that two react roots are rendered in isolation
     expect(firstRootDiv.firstChild.className).toBe('firstReactDiv');
     expect(secondRootDiv.firstChild.className).toBe('secondReactDiv');
 
     // Test that after unmounting each, they are no longer in the document.
-    ReactDOM.unmountComponentAtNode(firstRootDiv);
+    await act(() => {
+      firstRoot.unmount();
+    });
     expect(firstRootDiv.firstChild).toBeNull();
-    ReactDOM.unmountComponentAtNode(secondRootDiv);
-    expect(secondRootDiv.firstChild).toBeNull();
+    await act(() => {
+      secondRoot.unmount();
+    });
   });
 
   it('should warn when unmounting a non-container root node', () => {
@@ -46,6 +57,7 @@ describe('ReactMount', () => {
         <div />
       </div>
     );
+    // Cannot be migrated to createRoot until we remove unmountComponentAtNode i.e. remove this test.
     ReactDOM.render(component, mainContainerDiv);
 
     // Test that unmounting at a root node gives a helpful warning
@@ -69,6 +81,7 @@ describe('ReactMount', () => {
         </div>
       </div>
     );
+    // Cannot be migrated to createRoot until we remove unmountComponentAtNode i.e. remove this test.
     ReactDOM.render(component, mainContainerDiv);
 
     // Test that unmounting at a non-root node gives a different warning