Derived Values with $derived
Computing values from state that stay automatically in sync, without manually recalculating them yourself.
2 phút đọc
A lot of UI state isn't state at all — it's a calculation based on other state. A cart total, a filtered list, a formatted date: these shouldn't be stored and manually kept up to date, they should be derived. The $derived rune does exactly that.
<script>
let price = $state(20);
let quantity = $state(3);
let total = $derived(price * quantity);
</script>
<p>Total: ${total}</p>
<button onclick={() => quantity++}>Add one</button>total recalculates automatically whenever price or quantity changes — you never assign to total yourself, and you never had to list price and quantity as "dependencies" anywhere. Svelte's compiler sees which reactive values are read inside $derived(...) and wires up the tracking for you.
Why not just use $effect to set a variable?
You could imagine writing this with a plain $state variable updated inside $effect (covered in the next lesson):
<script>
let total = $state(0);
$effect(() => {
total = price * quantity;
});
</script>This works, but it's the wrong tool: total is now state that can drift out of sync (nothing stops other code from assigning to it directly), and it costs an extra reactive write on every recalculation. $derived values are read-only computed values, not independent state — there's no way to accidentally "un-sync" them, and Svelte can optimize the calculation more precisely because it knows the value is purely a function of its inputs.
$derived.by for longer calculations
For anything more involved than a single expression, $derived.by takes a function body:
<script>
let items = $state([
{ name: 'Book', price: 12, qty: 2 },
{ name: 'Pen', price: 2, qty: 5 },
]);
let total = $derived.by(() => {
let sum = 0;
for (const item of items) {
sum += item.price * item.qty;
}
return sum;
});
</script>
<p>Total: ${total}</p>Same rule applies: any reactive value read during that function's execution — here, items — becomes a tracked dependency, and the function re-runs whenever one of those values changes.
A rule of thumb
If a value can be calculated from other reactive values with no side effects, reach for $derived before $state or $effect. It keeps your component's data flow easy to trace: state is the source of truth, and derived values are pure reflections of it, never a second place the same information can get out of date.