Browse documentation

BEYOND QUICK START

Derive a value without duplicating state

Compute a second view of the count and follow both bindings through the component's lifetime.

Counter

0

Twice the count: 0

Start from the Quick Start counter and add a value computed from the count. Inside Counter, map the subject:

export const Counter = component(function* () {
  // Allocate per mounted view so separate counters keep independent state.
  const count = yield* RefSubject.make(0);

  // A read view avoids keeping a second mutable value in sync.
  const doubled = RefSubject.map(count, (value) => value * 2);

doubled observes the count. There is no second mutable value to keep in sync, and the button handlers stay the same. Display it below the controls:

<p>Twice the count: ${doubled}</p>

Each mounted counter owns its state and subscriptions. For the resource contract, see component lifetime.

Replace only src/Counter.ts. This version also spells out the button labels as Decrease and Increase. Click Increase twice: the count should be 2 and the doubled value 4.

Complete file

src/Counter.ts
import { RefSubject } from "@typed/fx";
import { component, html } from "@typed/template";

export const Counter = component(function* () {
  // Allocate per mounted view so separate counters keep independent state.
  const count = yield* RefSubject.make(0);

  // A read view avoids keeping a second mutable value in sync.
  const doubled = RefSubject.map(count, (value) => value * 2);

  return html`<section class="counter-demo" aria-label="Counter">
    <h2>Counter</h2>
    <div class="counter-demo__controls">
      <button type="button" onclick=${RefSubject.decrement(count)}>Decrease</button>
      <output aria-live="polite">${count}</output>
      <button type="button" onclick=${RefSubject.increment(count)}>Increase</button>
    </div>
    <p>Twice the count: ${doubled}</p>
  </section>`;
});

Try adding a derived sentence that distinguishes zero, one, and several clicks. Then build TodoMVC to use derived values in a complete client-side application.