sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
78.04k stars 4.08k forks source link

[Svelte5] Svelte mount duplicate issue #12010

Closed Neptunium1129 closed 2 months ago

Neptunium1129 commented 2 months ago

Describe the bug

https://github.com/flekschas/svelte-simple-modal

Breaking changes https://svelte-5-preview.vercel.app/docs/breaking-changes -- Components are no longer classes

i changed code new component code

old

new

Honeycam 2024-06-12 22-40-30

  1. Click to show modal.
  2. Press the space bar on your keyboard.

The temporary solution is to add "event.target.blur()" in the onclick function. However, this issue does not occur in Svelte 3 or 4.

Reproduction

REPL SVELTE5

Logs

No response

System Info

System:
    OS: Windows 10 10.0.19045
    CPU: (8) x64 Genuine Intel(R) CPU 0000 @ 1.60GHz
    Memory: 7.26 GB / 15.92 GB
  Binaries:
    Node: 20.14.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.22 - ~\AppData\Roaming\npm\yarn.CMD  
    npm: 10.7.0 - C:\Program Files\nodejs\npm.CMD   
  Browsers:
    Chrome: 125.0.6422.142
    Edge: Chromium (125.0.2535.92)
    Internet Explorer: 11.0.19041.4355
  npmPackages:
    svelte: ^5.0.0-next.1 => 5.0.0-next.148

Severity

annoyance

7nik commented 2 months ago

duplicate of #11973

Neptunium1129 commented 2 months ago

duplicate of #11973 I agree But this problem is cause svelte mount.

11973 is svelte fade

7nik commented 2 months ago

Locally, I enabled legacy.componentApi and modified the code to

      return function ModalComponent(anchor, props_) {
        let options = props_ ? {
          target: anchor.nodeType == 8 ? anchor.parentNode : anchor,
          props: props_,
        } : anchor;

    return new Component({
        ...options,
          props: {
            ...props,
            ...options.props,
          },
        });

And it still does double mounting. Well, under the hood, it still uses mount(). Also, for some reason, with enabled legacy.componentApi it tries to mount to a comment node :D

7nik commented 2 months ago

Hm, this

      return function ModalComponent(anchor, props2) {
     return Component(
            anchor,
           {
               ...props,
               ...props2,
      });
    }; 

doesn't cause double mounting.

If you do manual mounting, it's your responsibility to do manual unmounting. It just happened that at some points, Svelte sweeps away your manually mounted Popups. You can confirm this by adding an onDestroy logger to the Popup - it never logs in your REPL.

Neptunium1129 commented 2 months ago

thanks!!

dummdidumm commented 2 months ago

As pointed out, adjusting the generated code will resolve the issue. The problem was that calling mount was wrong in this instance, because the component is rendered by the framework, not instantiated manually. What the bind method does is decorate the component. here's the fixed playground.

Therefore closing.

Note this is all deep into advanced Svelte territory, so it's totally understandable that it's not easy to grasp right away.

Neptunium1129 commented 2 months ago

I just looked at the document, but it seems like something is very different. Thank you very much.