selectorFamily

Signature
selectorFamily<K, T>(factory: (key: K) => (get: GetFn) => T): SelectorFamily<K, T>

valdres Create a keyed collection of derived selectors

Creates a family of selectors keyed by a parameter. Each selector derives its value from atoms or other selectors based on the key.

The family object is a factory, not readable or subscribable state. Read or subscribe to a member such as userDisplayNameSelector("user-1"). Unlike an atomFamily, creating a selector-family member does not add store-local state or membership to enumerate.

Selector options apply to every family member. In particular, use { mutable: true } when results contain mutable built-ins or host objects; see the selector immutability contract.

Usage

import { selectorFamily } from "valdres"
import { userAtom } from "./userAtom"

const userDisplayNameSelector = selectorFamily(id => get => {
    const { firstName, lastName } = get(userAtom(id))
    return `${firstName} ${lastName}`
})

store.get(userDisplayNameSelector("user-1")) // "John Doe"

Custom key identity

Selector families use the same deterministic key codec as atomFamily: types and argument count are distinct, while plain Object keys and Map/Set contents are canonicalized independent of insertion order. Unsupported values (including Symbols, functions, Promises, class instances, and cycles) throw a TypeError.

Provide keyOf when the original argument is unsupported or when only part of it should determine selector identity:

const userRevision = selectorFamily(
    user => get => `${get(userAtom(user.id)).name}@${user.revision}`,
    { keyOf: user => [user.id, user.revision] },
)

With async computation

const userPostsSelector = selectorFamily(userId => get =>
    fetch(`/api/users/${userId}/posts`).then(res => res.json()),
)

As with selector(), the member getter itself must be synchronous. It may return a Promise, but a native async function is rejected because Valdres unwraps settled selector values and therefore cannot preserve an async function's always-Promise return contract.

In React

import { useValue } from "valdres-react"

function UserName({ userId }) {
    const displayName = useValue(userDisplayNameSelector(userId))
    return <span>{displayName}</span>
}

See also

  • selector — create a single selector
  • atomFamily — create a family of atoms
  • index — reactively filter an atom family by a term