bitovi / react-to-web-component

Convert react components to native Web Components. Works with Preact too!
https://www.bitovi.com/open-source/react-to-web-component
MIT License
644 stars 42 forks source link

Component is not unmounted #19

Closed ulich closed 2 years ago

ulich commented 2 years ago

When removing a web component element from the DOM, the underlying react component does not receive the unmount event:

Here is a demo to reproduce (also here https://codesandbox.io/s/relaxed-shamir-9ni71?file=/src/index.js):

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";
import reactToWebComponent from "react-to-webcomponent";

function App() {
  const [shown, setShown] = useState(false);
  return (
    <div>
      <button
        onClick={() =>
          setShown((wasShown) => {
            console.log(
              `Button clicked. Going to ${
                wasShown ? "hide" : "show"
              } the web component`
            );
            return !wasShown;
          })
        }
      >
        {shown ? "Hide" : "Show"}
      </button>

      {shown && <my-comp></my-comp>}
    </div>
  );
}

function MyComponent() {
  console.log("Rendering MyComponent");

  useEffect(() => {
    console.log("MyComponent mounted");
    return () => {
      console.log("MyComponent unmounted");
    };
  }, []);

  return <div>Hello</div>;
}

const WebComponent = reactToWebComponent(MyComponent, React, ReactDOM, {
  shadow: true,
});
customElements.define("my-comp", WebComponent);

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

When clicking the Show/Hide button, the console output is

index.js:12 Button clicked. Going to show the web component
index.js:30 Rendering MyComponent
index.js:33 MyComponent mounted
index.js:12 Button clicked. Going to hide the web component

As you see, the useEffect is called when mounting, but when unmounting, the cleanup function is never called.

justinbmeyer commented 2 years ago

Thanks!