Closed dnass closed 1 month ago
I think one question here is whether () => n
ought to be considered to change when n
changes (and thus, whether func
should be considered to change), and I don't know the answer to that. I'm thinking no, because evaluating () => n
doesn't involve evaluating n
, and so the dependence isn't established.
In Svelte 5 you generally should not need this pattern of capturing variables in functions via $:
declarations.
Dependencies are automatically tracked across function boundaries, so the function itself not changing should not matter for practical applications.
E.g. this does not work in Svelte 4 but just does in Svelte 5:
<script>
let n = 1;
function double() {
return n * 2;
}
</script>
<button on:click={() => n++}>{n}</button>
Double: {double()}
If you have a realistic use case where it does matter, please explain it.
And if you really really need something like this you can use $derived.by
<script>
let n = $state(0);
let func = $derived.by(() => {
n;
return () => n;
});
$effect(() => {
func, console.log('func changed'); // Effect does not run when n changes
});
</script>
<button onclick={() => n++}>Click</button>
As often, the question here is 'what are you actually trying to do?'
Maybe it's an outlier, but my use case does rely on triggering an effect when a function's dependencies change. In my svelte-canvas library, users define reactive functions that encapsulate pieces of canvas rendering logic. When any render function's dependencies change, the library clears the canvas and then reruns each render function. Here's a simple example in Svelte 4.
The render functions could just rerun with every rAF tick, but that would cause wasteful renders where nothing has changed. @paoloricciuti's suggestion works, but it's extra boilerplate for users. Either solution feels like a compromise compared with what's possible in Svelte 4.
Maybe it's an outlier, but my use case does rely on triggering an effect when a function's dependencies change. In my svelte-canvas library, users define reactive functions that encapsulate pieces of canvas rendering logic. When any render function's dependencies change, the library clears the canvas and then reruns each render function. Here's a simple example in Svelte 4.
The render functions could just rerun with every rAF tick, but that would cause wasteful renders where nothing has changed. @paoloricciuti's suggestion works, but it's extra boilerplate for users. Either solution feels like a compromise compared with what's possible in Svelte 4.
I think you can change your library to just call the render function in an effect...by doing so every reactive variable inside the function will be registered as a dependency
The render functions run in a specific order. If the changed function is called in an effect, that will happen first, and then trigger every other function to re-render in order (including the changed function, at its actual position in the sequence). The upshot is that each changed render function would run twice per frame instead of once.
The render functions run in a specific order. If the changed function is called in an effect, that will happen first, and then trigger every other function to re-render in order (including the changed function, at its actual position in the sequence). The upshot is that each changed render function would run twice per frame instead of once.
Maybe I'm missing something but something like this could work I think
I've used a set but you could just as well use an array if you want to insert in specific places. Basically the point is: you shouldn't use the effect to trigger the chained render but just call every render in an effect... everytime something changes the whole chain will be rerun
Describe the bug
In Svelte 4, it's possible to do:
The runes equivalent does not work:
If
func
is called within the$effect
callback, the effect runs. When it is only referenced, the effect does not run.Reproduction
https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE32PwWrDMAyGX0WIQh0a2p3TJFD2GMsOnS0XU1cKsRIoIe8-vHTsMNqDDvr060Oa0YdICauPGfl8I6zw1PdYot773KSJohKWmGQcbCZ1skPote2400gKDA1skp6VzFtx_KV-ZJsHjoYwkTOmgKYFXgO5NuQ9WX0M5h-seasEK5wk0j7KxWwz0iAMLAqBJ7mS266apej4pcoUz2T_RfXh7y-uv0ZVYRC2MdhrMz_O3-2W9j2T-rAmWizxJi74QA4rHUZaPpdv_HowmFQBAAA=
Logs
No response
System Info
Severity
blocking an upgrade