Consider the following svelte component
<script>
let x;
$: y = window.innerWidth;
</script>
<svelte.window bind:innerWidth={x} />
<h1>{x}</h1>
<h1>{y}</h1>
<h1>{window.innerWidth}</h1>
This renders three h1
HTML elements, which show the innerWidth
attribute of the window object.
However, only the first of them will update as you change the width of the window.
My question is why don't the other approaches update as the window width changes?
I'm new to javascript and svelte, but it looks as though <svelte.window /> is an import, which allows us to bind to the window object, which seems to allow us to "listen" to updates on window.innerWidth. But why not the other approaches? Why aren't they connected?
CodePudding user response:
svelte:window
is fairly magical1 but in general the rule is that reactivity is limited to local state (variables declared in a component), props (e.g. here bind:innerWidth
) and stores.
Since the other approaches access window.innerWidth
which is none of the above, the state will not update. The $:
cannot turn something that is not reactive into something reactive, it merely propagates existing reactivity.
1It internally uses events or observers to mimic the reactivity of regular Svelte components. It is not just reading window
properties.
The list of events used for the window
properties:
const associated_events = {
innerWidth: 'resize',
innerHeight: 'resize',
outerWidth: 'resize',
outerHeight: 'resize',
scrollX: 'scroll',
scrollY: 'scroll'
};