How to unmount something created with createRoot properly?
Asked Answered
B

1

8

I have a component that calls React 18's createRoot to render some content inside it often. My issue is that if I try to remove this with unmount on componentWillUnmount it will trigger a 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.

How to do this properly? This code was throwing no warnings in React 17 when I used ReactDOM.render(). Heres a minimal example:

import React from "react";
import { createRoot } from "react-dom/client";

class Example extends React.Component {
  componentWillUnmount() {
    if (this._root) {
      // This is causing the warning
      this._root.unmount();
    }
  }
  render() {
    return (
      <div
        ref={(el) => {
          if (el) {
            console.log("creating root");
            this._root = createRoot(el);
            this._root.render(<div>rendered with createRoot</div>);
          }
        }}
      />
    );
  }
}
class Example2 extends React.Component {
  render() {
    // just some code to trigger a re-render
    return (
      <div>
        {this.state?.aa ? <div>bbb</div> : <Example />}
        <button onClick={() => this.setState({ aa: true })}>click me</button>
      </div>
    );
  }
}
createRoot(document.getElementById("app")).render(<Example2 />);

codesandbox link

Boyd answered 19/7, 2022 at 21:49 Comment(0)
A
3

Do it asynchronous way

componentWillUnmount() {
    if (this._root) {
     
      setTimeout(()=> this._root.unmount())
  
    }
  }
Airscrew answered 13/9, 2022 at 12:12 Comment(1)
According by this, It may cause any issue in some cases. Please ensure your code once.Hydracid

© 2022 - 2024 — McMap. All rights reserved.