For
For reconciles a reactive array into the DOM. Each item renders once per unique key — no full re-renders on reorder, add, or remove. The render callback runs only for new keys.
API
import { For } from "elements-kit/for";
<ul> <For each={todos} by={(todo) => todo.id}> {(todo) => ( <li style:text-decoration={computed(() => todo.done ? "line-through" : "none")}> <input type="checkbox" checked={computed(() => todo.done)} on:change={() => (todo.done = !todo.done)} />{" "} {todo.text} </li> )} </For></ul>| Prop | Type | Description |
|---|---|---|
each | T[] | (() => T[]) | Reactive array to render. |
by | (item: T, index: number) => string | number | Key function. Defaults to the index. |
children | (item: T, index: number) => Element | Render function. Called once per new key. |
How reconciliation works
On each array change, For compares the new keys to the previous ones:
- Existing key → reuses the rendered node. No teardown, no recreate.
- New key → calls the render function once and mounts the result.
- Missing key → unmounts the node.
- Moved key → reorders the DOM in place.
Complexity is O(n + m) where n is the old array length and m is the new.
Per-item scope
Each item’s render callback runs inside its own effectScope. onCleanup calls and nested effects registered during render belong to that scope and fire when the item’s key leaves each — not only when the whole list unmounts. Use this to bind row-level resources (subscriptions, intervals, observers) to the row’s real lifetime. See Scopes & cleanup.
Keys
Keys must be unique within each. Duplicate keys produce undefined reordering. If your data doesn’t have a natural identifier, generate one at insertion time; don’t rely on index as a key for mutable lists.
Non-reactive arrays
each accepts both a plain array and a signal / getter. A plain array renders once; passing a signal makes the list live:
// Static — rendered once<For each={[1, 2, 3]} by={(n) => n}>{(n) => <li>{n}</li>}</For>
// Reactive — reruns on signal changeconst items = signal<string[]>([]);<For each={items} by={(x) => x}>{(x) => <li>{x}</li>}</For>