computed()

Create a derived signal that automatically recomputes when its dependencies change.

const derived = computed(fn)

Parameters

ParameterTypeDescription
fn () => T A function that computes the derived value. All signals read inside this function are automatically tracked as dependencies.

Returns

A read-only signal with the following methods:

MethodDescription
derived() Read the current computed value (creates subscription in reactive contexts)
derived.peek() Read the value without creating a subscription

Usage

Basic Derived Value

import { signal, computed } from 'what-framework';

const firstName = signal('John');
const lastName = signal('Doe');

const fullName = computed(() =>
  `${firstName()} ${lastName()}`
);

console.log(fullName());  // "John Doe"

firstName.set('Jane');
console.log(fullName());  // "Jane Doe"

Filtering and Transforming Data

const todos = signal([
  { text: 'Learn What', done: true },
  { text: 'Build app', done: false },
  { text: 'Deploy', done: false },
]);

const remaining = computed(() =>
  todos().filter(t => !t.done)
);

const count = computed(() => remaining().length);

console.log(count());  // 2

In Components

Props arrive exactly as the caller passed them. Call a prop only when the caller passes a signal, and say so at the call site, otherwise the component throws TypeError: price is not a function.

import { signal, computed, mount } from 'what-framework';

/* price and taxRate are signal accessors, not numbers */
function PriceDisplay({ price, taxRate }) {
  const total = computed(() =>
    price() * (1 + taxRate())
  );

  return <span>Total: ${() => total().toFixed(2)}</span>;
}

const price = signal(10, 'price');
const taxRate = signal(0.2, 'taxRate');

mount(<PriceDisplay price={price} taxRate={taxRate} />, '#app');

For plain-value props, drop the calls. The component then renders once with the values it was given:

function PriceDisplay({ price, taxRate }) {
  const total = price * (1 + taxRate);

  return <span>Total: ${total.toFixed(2)}</span>;
}

mount(<PriceDisplay price={10} taxRate={0.2} />, '#app');

Chaining Computeds

const items = signal([10, 20, 30]);
const doubled = computed(() => items().map(x => x * 2));
const sum = computed(() => doubled().reduce((a, b) => a + b, 0));

console.log(sum());  // 120

Notes

  • Lazy evaluation -- Computed values do not run until first read. They only recompute when a dependency changes AND the value is read.
  • Cached -- Repeated reads return the cached value without recomputing, until a dependency changes.
  • Read-only -- Computed signals have no .set() method. They derive their value entirely from other signals.
  • Auto-tracked dependencies -- Any signal read inside the function is tracked automatically. Conditional reads are tracked only when that branch executes.
  • Use signal() for writable state, and computed() for derived values. Avoid using effect() to sync a signal with a computed expression.