svelte icon indicating copy to clipboard operation
svelte copied to clipboard

Slot property change triggers object invalidation in child component

Open stanf0rd opened this issue 2 years ago • 1 comments

Describe the bug

  1. If you use some slot-property: <slot {prop} />
  2. ...and passes inside that slot a component (e.g. Content.svelte), which receives some object as a prop, and that object was extracted from store in that component:
<script>
  ...
  $: object = $store
</script>

<Wrapper> <!-- slot props are in Wrapper, but we even don't need to use them outside -->
  <Content {object} />
</Wrapper>
  1. ...and that store was somewhere updated based on other store, even just once (via subscription or somehow else):
// simple update
store.update(state => {
  $someOtherStore // use other store anyhow in our first store update
  return state
})

// or subscription
const unsub = someOtherStore.subscribe(() => {
  store1.update(state => state)
})
// immediately unsubscribe
// (but if `someOtherStore` just doesn`t update — you don`t need unsubscription)
unsub()
  1. ...then your object invalidates every time slot prop updates, and triggers all reactivity statements based on it in child component:
// Content.svelte

<script>
  export let object

  // store was not changed, but reactive statement fires every time, when slot property on parent slot updates
  $: console.log({ object })
</script>

As workaround you can pass object via context.

Reproduction

https://svelte.dev/repl/106356ce31de4abd85b52f3a577fada9?version=3.55.0

Logs

No response

System Info

System:
    OS: macOS 13.0.1
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 692.20 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.10.0 - /usr/local/bin/node
    Yarn: 1.22.17 - /usr/local/bin/yarn
    npm: 8.19.2 - /usr/local/bin/npm
  Browsers:
    Chrome: 108.0.5359.124
    Firefox: 104.0
    Safari: 16.1
  npmPackages:
    svelte: 3.54.0 => 3.54.0

Severity

annoying

stanf0rd avatar Dec 22 '22 21:12 stanf0rd

I made much simpler REPL: https://svelte.dev/repl/6b5ac21cf0684cce805397e975929475?version=3.55.0

You don't really need stores. Looks like reason is that slot prop invalidates all slot's child components, even if they don't use the slot prop.

stanf0rd avatar Dec 22 '22 21:12 stanf0rd

This will be fixed in Svelte 5.

dummdidumm avatar Nov 15 '23 12:11 dummdidumm