Course outline

Svelte / Basic: reactive components and ownership / Lesson 2

State, derived values and reactive identity

Use explicit state and pure derivation while keeping proxy identity and ordinary JavaScript snapshots distinct.

About 4 min readContent reviewed
On this page

Lesson goals

  • Explain $state and $derived under Svelte 5 runes mode.
  • Avoid copied snapshots and effect-based duplication of derived state.

Declare the source and compute what follows from it

In runes mode, $state marks reactive state and $derived describes a value computed from reactive inputs. A simple counter can derive its doubled value without maintaining a second manually synchronized counter. Derivations should be free of side effects; writing to a server or changing unrelated state during calculation creates an unclear execution contract. A rune is compiled syntax, so a plain Node function with similar arithmetic does not test Svelte reactivity. Keep domain calculations independently testable, then verify the compiled component and its actual dependency tracking in an appropriate integration.

Read and write state directly in the compiled component

The component uses a numeric $state and derives double. The click handler increments the source rather than independently updating both values. The reasoned initial labels are zero and zero, then one and two after one click under the declared code. No compiler, DOM or event was run here. Runes values are read as ordinary-looking variables; adding an invented .value wrapper would change the program incorrectly. Keep business validation separate: a reactive quantity can still be outside the permitted domain range and should not be trusted merely because the screen updates.

svelte Illustrative state and pure derivation
<script>
  let count = $state(0);
  let double = $derived(count * 2);
</script>
<button onclick={() => count += 1}>Count {count}</button>
<p>Double {double}</p>

The displayed sequence is reasoned from the fragment, not measured. The example was not compiled or clicked.

Know which values remain reactive and which are snapshots

$state can create deeply reactive proxies for ordinary objects and arrays under its documented rules. It does not make every arbitrary class instance or external object universally reactive. Destructuring or passing a primitive value can capture the current value rather than a live relationship. Choose a getter or another explicit interface when later reads must observe current state. $state.raw and snapshot APIs have different purposes and should not be mixed with deep mutation assumptions. Review nested ownership as well as outer identity; two fresh wrappers can still share an inner mutable object.

Test the domain arithmetic without claiming proxy behavior

The local function totals published synthetic course durations and returns zero for an empty list. It does not observe a proxy, track dependencies or subscribe to updates. This makes the domain rule reproducible while keeping its scope honest. A compiled component can use an equivalent pure calculation inside a derived expression, but needs separate tests for list mutation and input replacement. Validate duration units and nonnegative values in the real data boundary rather than letting an arbitrary string participate in addition. Reactivity cannot repair malformed source data.

javascript Complete offline duration calculation
function minutes(rows) {return rows.filter(r=>r.published).reduce((sum,r)=>sum+r.minutes,0);}
console.assert(minutes([{published:true,minutes:15},{published:false,minutes:40},{published:true,minutes:5}])===20);
console.assert(minutes([])===0);

The published rows total twenty minutes and the empty list totals zero. No Svelte dependency tracking is tested.

Keep derived meaning and asynchronous work separate

Prefer derivation when a value is determined by current state. Use effects for an actual external synchronization need, not as a default way to copy one state variable into another. Async source work also needs request ownership, error handling and protection from late stale results. A derived value is not a database revision or mutation acknowledgment. When refactoring reactive logic into .svelte.js or .svelte.ts modules, use the documented compilation context and preserve how consumers read current values. This course executes only the duration calculation, not runes, proxies, update scheduling or a refactored reactive module.

Common errors and fixes

An ordinary state-object destructure stays old

Why it happens
A current primitive snapshot was mistaken for a live reactive relationship.
How to fix it
Use the documented current-value access pattern or explicit getter.
Prevent it next time
Test both nested mutation and input replacement in the compiled component.

Two manually synchronized values drift

Why it happens
Derived meaning was duplicated as independent state.
How to fix it
Keep one source and compute the dependent value purely.
Prevent it next time
Test all source-change paths rather than one button.

Every object is assumed deeply reactive

Why it happens
The documented proxy rules were generalized to arbitrary values.
How to fix it
Review the actual object type and selected state API.
Prevent it next time
Separate plain-object, class and raw-state fixtures.

Check your understanding

1. Does the minutes test prove that changing a Svelte list updates the UI?

Show worked solution

No. It proves a plain arithmetic/filtering rule for supplied arrays. It never compiles a rune or tracks a dependency. Keep that evidence and separately test the componentโ€™s source updates, replacement behavior and rendered result in an authorized isolated compiler/browser integration.

2. Why should a derived expression not write to a server?

Show worked solution

Its purpose is to compute a value from current inputs, and reevaluation follows reactive execution rather than a unique confirmed user intent. A write can repeat or occur unexpectedly. Keep the expression pure and use a validated authorized action with explicit replay handling for durable changes.

Key takeaways

  • Explicit sources and pure derivation keep reactive meaning clear.
  • Snapshots, proxies and domain validity are distinct concerns.

Official references