map()
The map() function renders a reactive array as a list of elements.
Loading sandbox...
Syntax
Section titled “Syntax”// Primitives (auto-keyed by value)map(items, render)
// Objects (explicit key function)map(items, keyFn, render)Parameters
Section titled “Parameters”items
: A reactive array (signal or computed).
keyFn (required for objects)
: A function that returns a unique identifier for each item.
render
: A function that returns an element spec for each item. Receives a signal wrapping the item.
Description
Section titled “Description”Primitive arrays
Section titled “Primitive arrays”For arrays of strings or numbers, the value itself is used as the key:
const items = signal(['Apple', 'Banana', 'Cherry']);
el('ul')( map(items, (item) => el('li')(item)))Object arrays
Section titled “Object arrays”For objects, provide a key function to track identity:
const todos = signal([ { id: 1, text: 'Learn', done: false }, { id: 2, text: 'Build', done: false },]);
el('ul')( map( todos, (todo) => todo.id, // key function (todo) => el('li')( // render function computed(() => todo().text) ) ))Item signals
Section titled “Item signals”The render function receives a signal wrapping each item, not the plain value. This enables reactive updates when items change:
map(todos, t => t.id, (todo) => { // todo is a signal, read it to get the value return el('li')( computed(() => todo().text), computed(() => todo().done ? '✓' : '') );})When you update an item in the source array, the corresponding item signal updates — the element isn’t recreated:
// Update one todo — the element updates reactivelytodos(arr => arr.map(t => t.id === 1 ? { ...t, done: true } : t));Examples
Section titled “Examples”Simple list
Section titled “Simple list”const names = signal(['Alice', 'Bob', 'Carol']);
el('ul')( map(names, (name) => el('li')(name)))
// Add itemnames([...names(), 'Dave']);
// Remove itemnames(names().filter(x => x !== 'Bob'));Todo list
Section titled “Todo list”type Todo = { id: string; text: string; done: boolean };
const todos = signal<Todo[]>([]);
const toggle = (id: string) => { todos(todos().map(t => t.id === id ? { ...t, done: !t.done } : t ));};
const remove = (id: string) => { todos(todos().filter(t => t.id !== id));};
el('ul')( map(todos, t => t.id, (todo) => el('li').props({ style: computed(() => todo().done ? 'text-decoration: line-through' : '' ), })( el('input').props({ type: 'checkbox', checked: computed(() => todo().done), onchange: () => toggle(todo().id), })(), computed(() => todo().text), el('button').props({ onclick: () => remove(todo().id) })('×') ) ))Nested lists
Section titled “Nested lists”type Category = { id: string; name: string; items: string[] };
const categories = signal<Category[]>([...]);
el('div')( map(categories, c => c.id, (category) => el('section')( el('h2')(computed(() => category().name)), el('ul')( map( computed(() => category().items), (item) => el('li')(item) ) ) ) ))With index
Section titled “With index”If you need the index, derive it from the array position:
const items = signal(['A', 'B', 'C']);
el('ol')( map(items, (item, index) => el('li')(computed(() => `${index() + 1}. ${item()}`)) ))See also
Section titled “See also”- el() — Create elements
- match() — Conditional rendering
- iter() — The data structure powering
map() - Signal Patterns — Patterns for arrays and collections