createProjection
Edit this pageimport { createProjection } from "solid-js/store"
function createProjection<T>( fn: (draft: T) => T | void, initial?: T, options?: { key?: string }): Store<T>createProjection creates a mutable derived store (a projection). The derive function receives a draft that you can mutate. It replaces createSelector with a more general tool.
How it works
- The derive function receives a mutable draft that you can modify
- If the function returns a value, that value is reconciled into the projection (preserving identity for unchanged entries, keyed by
options.key, default"id") - If the function does not return, the mutations are applied directly
Selection pattern
Replace createSelector with a projection that updates only the affected keys:
import { createSignal } from "solid-js"import { createProjection } from "solid-js/store"
const [selectedId, setSelectedId] = createSignal("a")
const selected = createProjection((s) => { const id = selectedId() s[id] = true if (s._prev != null) delete s[s._prev] s._prev = id}, {})Use in JSX:
<For each={items()}> {(item) => ( <li class={selected[item().id] ? "selected" : ""}> {item().name} </li> )}</For>Reconciled list data
When the derive function returns a value, it's reconciled into the projection. This is useful for async data:
const users = createProjection(async () => { return await api.listUsers()}, [], { key: "id" })Reconciliation preserves object identity for unchanged entries, making it efficient for keyed list rendering.
createStore(fn) shorthand
createStore(fn, initial?, options?) is effectively a shorthand for creating a derived store using the projection mechanism:
import { createStore } from "solid-js/store"
const [cache] = createStore((draft) => { draft.value = expensive(selector())}, { value: 0 })Migration from createSelector
// 1.ximport { createSelector } from "solid-js"const isSelected = createSelector(selectedId)// In JSX: isSelected(item.id)
// 2.0import { createProjection } from "solid-js/store"const selected = createProjection((s) => { const id = selectedId() s[id] = true if (s._prev != null) delete s[s._prev] s._prev = id}, {})// In JSX: selected[item.id]