sveltejs / svelte

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

`bind:this` weird behavior #12769

Open CNSeniorious000 opened 1 month ago

CNSeniorious000 commented 1 month ago

Describe the bug

<Container>
  <div bind:this={ref}>
    <Content {ref} />
  </div>
</Container>

When Container got updated, the div seems to be a new one, but the ref points to the old one.

Reproduction

open_in_stackblitz

Logs

No response

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    svelte: ^4.2.7 => 4.2.18

Severity

annoyance

paoloricciuti commented 1 month ago

This behaviour seems fixed in svelte 5 so i don't know if it will be back ported to svelte 4.

PatrickG commented 1 month ago

I don't get this. In the reproduction Container does nothing except rendering its children. What should update in there? inside in Content is true. I also modified Content to check if the .parentElement of the <pre> is the same as ref, and that is true as well.

Changed `Content.svelte` ```svelte

The element:
  {ref}

Is it inside the document?
  {inside}

Is pre.parentElement === ref
  {isSame}

(it should be!)

```
paoloricciuti commented 1 month ago

I don't get this. In the reproduction Container does nothing except rendering its children. What should update in there? inside in Content is true. I also modified Content to check if the .parentElement of the \<pre\> is the same as ref, and that is true as well.

Changed Content.svelte

<script>
  export let ref;
  let pre
  $: inside = ref && document.contains(ref);
  $: isSame = ref && pre && pre.parentElement === ref;
</script>

<pre bind:this={pre}>

The element:
  {ref}

Is it inside the document?
  <span style:color={inside ? "green" : "red"}>{inside}</span>

Is pre.parentElement === ref
  <span style:color={isSame ? "green" : "red"}>{isSame}</span>

(it should be!)

</pre>

<style>
  span {
    font-weight: bold;
  }
</style>

To see the behavior you should modify the readme to trigger HMR.

PatrickG commented 1 month ago

To see the behavior you should modify the readme to trigger HMR.

Oh, this is a HMR issue. Thanks for the explanation.

CNSeniorious000 commented 1 month ago

Sorry for missing description. This reproduction is a simplified one. In my realworld use case, the Container component depends on some useful files. Changing them will trigger an HMR which behaves wrongly. In this demo, I change that to a useless import to README.md, which may be confusing.