Skip to content

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>
PropTypeDescription
eachT[] | (() => T[])Reactive array to render.
by(item: T, index: number) => string | numberKey function. Defaults to the index.
children(item: T, index: number) => ElementRender 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 change
const items = signal<string[]>([]);
<For each={items} by={(x) => x}>{(x) => <li>{x}</li>}</For>

See also