computed()
Create a derived signal that automatically recomputes when its dependencies change.
const derived = computed(fn)
Parameters
| Parameter | Type | Description |
|---|---|---|
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:
| Method | Description |
|---|---|
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.