Askr documentation
Fundamentals

State and Derived Values

Read and write state through explicit getter/setter pairs, and derive values instead of synchronizing copies.

Example

import { derive, state } from '@askrjs/askr';

export function OrderTotal() {
  const [quantity, setQuantity] = state(2);
  const [unitPrice] = state(12);
  const total = derive(() => quantity() * unitPrice());

  return <button onClick={() => setQuantity((value) => value + 1)}>Total: {total()}</button>;
}

Create state

Call `state(initialValue)` inside a component and destructure the result as `const [count, setCount] = state(0)`. Read with `count()` and write with `setCount(...)`. Under the hood each call records itself against the current component instance, so calling `state()` outside of render — at module scope or inside an event handler — throws instead of silently creating orphaned state.

Read and update state

Read a state cell by calling it, `count()`, and update it by calling `setCount(nextValue)` or `setCount(prev => prev + 1)` when the next value depends on the previous one. Reading state inside a component body is what wires that component up to future updates; reading it outside render (in a plain callback, for instance) just returns a snapshot without subscribing to anything.

Derived values

`derive(fn)` computes a value from other reactive sources and re-evaluates only when one of those sources changes, returning a `Derived<T>` that's callable just like state. It also supports a two-argument form, `derive(source, map)`, for mapping over another readable source such as a resource or query result. Because derived values are read the same way as state, you can swap one for the other without touching the calling code.

Selectors and subscriptions

`selector(source, equals?)` builds a fine-grained subscription: it watches `source()` and returns a predicate you call with a candidate value to check equality, so a component only re-renders when that specific comparison flips rather than whenever the underlying source changes at all. The optional `equals` function lets you customize comparison beyond `===`, which matters for objects or normalized IDs. This is the tool for list items or tabs that need to know "am I the selected one" without subscribing to the whole selection value.