selector

Signature
selector<T>(getter: (get: GetFn) => T): Selector<T>

valdres Derive computed state that updates automatically

Creates derived state that automatically recomputes when its dependencies change. Selectors are read-only — they compute their value from atoms and other selectors.

Usage

import { atom, selector } from "valdres"

const firstNameAtom = atom("John")
const lastNameAtom = atom("Doe")

const fullNameSelector = selector(get => {
    const first = get(firstNameAtom)
    const last = get(lastNameAtom)
    return `${first} ${last}`
})

Parameters

ParameterTypeDescription
getter(get: GetFn) => TA function that computes the derived value. Use get() to read atoms or other selectors.
options.namestringOptional name for debugging, devtools, and validation error messages
options.schemaSchema<T>Schema for runtime validation of the selector's result, and type inference. A no-op unless validation is enabled. See Schema Validation.
options.schemaValidationbooleanPer-selector override of the store's schemaValidation flag — true always validates this selector, false exempts it
options.mutablebooleanOpt out of development/test deep-freezing. Required when results contain mutable built-ins or host objects that cannot be frozen safely.

Selectors follow the same immutability and exotic-value contract as atoms. When a selector returns a value from a mutable atom unchanged, mark the selector mutable: true as well so its cache does not attempt to deep-freeze that value.

Async selectors

Selectors can return a promise. They work with Suspense in React. Note that the getter itself must be a sync function that returns a promise — selector() rejects async functions at creation time:

const userDataSelector = selector(get => {
    const userId = get(userIdAtom)
    return fetch(`/api/users/${userId}`).then(res => res.json())
})

Schema validation

A selector's schema validates its computed result on every evaluation — a runtime contract that catches a selector drifting from its declared shape:

const fullNameSelector = selector(
    get => `${get(firstNameAtom)} ${get(lastNameAtom)}`,
    { name: "fullName", schema: z.string() },
)

Validation is opt-in per store (store({ schemaValidation: true })) or per selector (schemaValidation: true). See the Schema Validation guide.

See also