plasmo icon indicating copy to clipboard operation
plasmo copied to clipboard

[BUG] CSUI duplicated with PlasmoGetInlineAnchorList

Open yaozhiwang opened this issue 1 year ago • 2 comments

What happened?

Using PlasmoGetInlineAnchorList with <h1> as anchor in https://docs.plasmo.com/, there will be two CSUI shown:

image

And then, if I click some links in the navigation on the left, more and more CSUIs show up:

image

Not sure whether it is related to #292

Steps to reproduce:

  1. create a new plasmo project with contents/inline: pnpm create plasmo --entry=contents/inline
  2. edit and change contents/inline.tsx to
import type { PlasmoCSConfig, PlasmoGetInlineAnchorList } from "plasmo"

export const config: PlasmoCSConfig = {
  matches: ["https://docs.plasmo.com/*"]
}

export const getInlineAnchorList: PlasmoGetInlineAnchorList = () =>
  document.querySelectorAll("h1")

// Use this to optimize unmount lookups
export const getShadowHostId = () => "plasmo-inline-example-unique-id"

const PlasmoInline = () => {
  return <button>Custom button</button>
}

export default PlasmoInline

Version

Latest

What OS are you seeing the problem on?

MacOSX

What browsers are you seeing the problem on?

Chrome

Relevant log output

No response

(OPTIONAL) Contact Details

No response

Code of Conduct

  • [X] I agree to follow this project's Code of Conduct
  • [X] I checked the current issues for duplicate problems.

yaozhiwang avatar Apr 19 '23 15:04 yaozhiwang

Same here. Each new mount new Component is created but old one is never removed. and the destructor is never called.

export const Default = ({ anchor }) => {
  useEffect(() => {
    console.log("useEffect", anchor);
    return () => {
      console.log("useEffect distruct", anchor);
    };
  }, []);

veedeo avatar Feb 18 '24 16:02 veedeo

Ok so I debugged the code and looks like the issue is at this line mountState.hostSet.delete(el) once element was removed from DOM we need also to call root.unmount() @louisgv Can you advice how to best approach this change?

// Go through mounted sets and check if they are still mounted
    for (const el of mountState.hostSet) {
      if (isMounted(el)) {
        const anchor = mountState.hostMap.get(el)
        if (!!anchor) {
          if (anchor.type === "inline") {
            mountedInlineAnchorSet.add(anchor.element)
          } else if (anchor.type === "overlay") {
            overlayHost = el
          }
        }
      } else {
        mountState.hostSet.delete(el)
      }
    }

veedeo avatar Feb 18 '24 20:02 veedeo