Svelte
svelte/derived-not-effect
A value computed from state is a $derived, not a $state that an $effect keeps in sync.
moderatestaticfe-svelte
Why
An effect runs after the update, so the synced value is stale for one render, the component updates twice, and two pieces of state can drift apart. Effects that write state are the usual start of update loops (effect_update_depth_exceeded) and make the data flow hard to follow.
Fix
Declare the value with $derived(expression), or $derived.by(() => { ... }) for several statements. Deriveds can be overridden by assignment (an optimistic value) and recompute when their inputs change. Keep $effect for work outside Svelte: a canvas, a third-party widget (better: {@attach}), analytics.
Examples
<!-- bad -->
<script>
let { items } = $props()
let visible = $state([])
$effect(() => { visible = items.filter((item) => !item.hidden) })
</script>
<!-- good -->
<script>
let { items } = $props()
let visible = $derived(items.filter((item) => !item.hidden))
</script>Sources
Facts
- Id
svelte/derived-not-effect- Severity
- moderate
- Check
- static checked in the source by
audit - Applies to
svelte- Only in projects with
sveltesveltekit- Taught by the skill
fe-svelteSvelte components- Since version
- 0.1.0
Read it in the terminal
npx github:dawidolko/frontend-skills explain svelte/derived-not-effect