-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
Describe the problem
High frustration with $effect and deep function calls.
Is this really, how it was designed?
Recommendation: Add new rune like $effect.deep() - if this is necessary in very rare cases.
Default $effect should not go beyound 1st level.
This deep behavior is not correct documented in docs:
https://svelte.dev/docs/svelte/$effect
$effect automatically picks up any reactive values ($state, $derived, $props) that are synchronously read inside its function body and registers them as dependencies. When those dependencies change, the $effect schedules a rerun.
<script>
let count = $state(0)
$effect(() => deep())
function deep() {
deeper()
}
function deeper() {
count = count + 1
//here is no limit, how deep tracking can go
//Error: effect_update_depth_exceeded Maximum update depth exceeded.:
}
</script>
{count}
Another high frustration level with $effect.
It took me 1h to find the problem.
<script>
import {untrack} from 'svelte'
let nav = $state()
$effect(() => {
nav = []
//nav.push('a') //<<< endless loop
//untrack(() => nav).push('a') //<<< endless loop
untrack(() => nav.push('a')) //ok
})
</script>
I did not expect a "read" with nav.push() - on second view this was clear.
But I did not expect a "read" with untracked nav
How can this happen, if nav is already untracked?
Only untracking whole nav.push() runs well.
This behavior should also be documented
Recommendation:: Add untrackAll() - which will disable any tracking "reads" - so you don't need to write untrack all the time, if you call push for example.
$effect(() => {
untrackAll(nav, morevariables...)
nav = []
nav.push('a')
nav.push('b')
nav.push('c') //don't need untrack all the time
})
or opposite to react: a non-tracking array (optional):
$effect(() => {
nav = []
nav.push('a')
nav.push('b')
nav.push('c')
}, [nav, morevariables...])
Describe the proposed solution
see above
Importance
would make my life easier