Svelte 12: $derived.by — Derivaciones Multi-Sentencia
easy⏱ 5 mincoursesvelte
$derived vs $derived.by
$derived acepta exactamente una expresión — sin punto y coma, sin loops for, sin let local dentro. En el momento en que tu cálculo necesita más que eso (recorrer un carrito para sumar totales, lógica con ramas, armar un string pieza por pieza), recurrís a $derived.by(() => {...}). Es el mismo motor de rastreo de dependencias por debajo; solo te da un cuerpo de función real con el que trabajar.
<script>
let count = $state(4);
// OK: single expression
let doubled = $derived(count * 2);
// NOT valid: $derived only takes an expression
// let sum = $derived(() => { let s = 0; for (...) s += x; return s; });
// Correct: use $derived.by for a function body
let sum = $derived.by(() => {
let s = 0;
for (let i = 0; i < count; i++) s += i;
return s;
});
</script>
Cada valor que leés adentro se vuelve una dependencia
En la tienda de abajo, total lee items (recorriéndolo en loop), y discount lee total. Como $derived.by rastrea lecturas dinámicamente — no mediante un array de dependencias declarado — discount se recalcula automáticamente cada vez que total cambia, que a su vez se recalcula cada vez que cambia el qty de algún item. Probá hacer clic en '+1' en un item y mirá cómo discount y total se actualizan en cascada.
$derived.by sigue siendo de solo lectura, sigue cacheado
Igual que $derived, el valor que retorna $derived.by está memoizado — Svelte solo vuelve a ejecutar la función cuando una dependencia rastreada realmente cambia, no en cada render, y no podés asignarle directamente (total = 5 sería un error). Si necesitás lógica imperativa con efectos — no un valor computado puro — para eso está $effect, que viene a continuación.