Skip to content

Collections

The <collection> element renders a list of components from an array on your state. It handles dynamic addition, removal, filtering, and sorting automatically.

function TodoList({ state }) {
return (
<div>
<collection of={TodoItem} from="items" />
</div>
)
}
TodoList.initialState = {
items: [
{ id: 1, text: 'Learn Sygnal', done: false },
{ id: 2, text: 'Build something', done: false }
]
}

Each item in the items array becomes the state for one TodoItem instance. If a TodoItem updates its state, the corresponding array entry is updated. If a TodoItem sets its state to undefined, it is removed from the array.

PropTypeDescription
ofComponentThe component to render for each item
fromString or LensThe state property (or lens) containing the array
filterFunctionFilter function — only items returning true are shown
sortString, Object, Array, or FunctionSort items — see Sorting below
classNameStringCSS class for the wrapping container
<collection
of={TodoItem}
from="items"
filter={item => !item.done}
/>

The sort prop accepts several formats for controlling sort order.

<collection of={TodoItem} from="items" sort="text" />

Use an object with the property name as key and "asc" or "desc" as value:

<collection of={TodoItem} from="items" sort={{ text: "desc" }} />

You can also use 1 (ascending) or -1 (descending):

<collection of={TodoItem} from="items" sort={{ priority: -1 }} />

For arrays of strings or numbers (not objects), pass "asc" or "desc" directly:

<collection of={TagItem} from="tags" sort="asc" />

Pass an array to sort by multiple fields. Each entry can be a string (ascending), object (with direction), or function:

<collection of={TodoItem} from="items" sort={[
{ priority: "desc" },
"text"
]} />
<collection of={TodoItem} from="items" sort={(a, b) => a.createdAt - b.createdAt} />

Collections automatically use the id property of each item for efficient rendering. If items don’t have an id, the array index is used.

An item can remove itself from the collection by returning undefined from a reducer:

TodoItem.model = {
DELETE: () => undefined // removes this item from the array
}

You can also import and use the capitalized Collection component:

import { Collection } from 'sygnal'
function TodoList({ state }) {
return (
<div>
<Collection of={TodoItem} from="items" className="todo-list" />
</div>
)
}