svelte
svelte copied to clipboard
Slot property change triggers object invalidation in child component
Describe the bug
- If you use some slot-property:
<slot {prop} /> - ...and passes inside that slot a component (e.g.
Content.svelte), which receives someobjectas a prop, and that object was extracted fromstorein 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>
- ...and that
storewas 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()
- ...then your
objectinvalidates 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
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.
This will be fixed in Svelte 5.