Skip to content

state / derived

state count: number = 0

state declares typed, reactive local state. It compiles to a useState. Inside an action, assigning to a state name (count = count + 1) is a reactive write — the compiler emits the setter call.

state is ephemeral: it resets when the component unmounts (it’s useState). To persist a value across route changes, use a store.

derived label = count === 1 ? "1 click" : `${count} clicks`

derived is a value computed from other reactive sources. You read it; you never call it or assign to it. It recomputes when its inputs change. The compiler emits a plain expression (and only reaches for useMemo when the computation is expensive enough to warrant it).

export component Cart {
state items: string[] = []
derived count = items.length
derived isEmpty = count === 0
view {
<p>{isEmpty ? "Cart is empty" : `${count} items`}</p>
}
}
Compiled React 19 — this is the file in your repo
import { useEffect, useMemo, useState } from "react"
export const Cart = () => {
const [items, setItems] = useState(([]) as string[])
const count = useMemo(() => items.length, [items])
const isEmpty = useMemo(() => count === 0, [count])
useEffect(() => { const h = globalThis.__REACTRA_TEST__; if (h) h.update("Cart", { items, count, isEmpty }) })
return (<>
<p>{isEmpty ? "Cart is empty" : `${count} items`}</p>
</>)
}
export default Cart

Gotcha: keep derived pure — no side effects, no async. For async, use a resource; for side effects, use an effect.

Next: resource + await/pending/error.