Lists

Sinuous provides a submodule called map to make rendering large lists as snappy as possible.

Without map

It is possible to create lists without this module but the drawback is that it would re-render each element in the list every time an item gets added or removed. Lets take a a look at that first.

import { o, html } from 'sinuous';

const list = o([1, 2, 3, 4, 5]);
const view = () => html`
<ul>
${() =>
list().map(
i =>
html`
<li>${i}: ${Date.now()}</li>
`

)}

</ul>
`
;

Try it on Codesandbox

Rendering a list without the map module can still be useful if the number of items is fairly small and it's technically not an issue all elements get re-rendered or if the list has a static number of items but the content in each item is dynamic.

import { o, html } from 'sinuous';

const list = [{ name: o('John') }, { name: o('Lisa') }, { name: o('Pete') }];
const view = () => html`
<ul>
${list.map(
obj =>
html`
<li>${obj.name}</li>
`

)}

</ul>
`
;

document.body.append(view());

// Change observable value of the 3rd item in the list.
list[2].name('Jack');

Try it on Codesandbox

With map

In a lot of cases you'll find yourself with a list that'll change in the number of items and then it's recommended to use the provided map module.

This module will make a diff of the new state with the old state and make the least amount of DOM operations to create the new view.

import { o, html } from 'sinuous';
import { map } from 'sinuous/map';

const list = o([
{ id: 1, text: o('bread') },
{ id: 2, text: o('milk') },
{ id: 3, text: o('honey') },
{ id: 4, text: o('chips') },
{ id: 5, text: o('cookie') }
]);
const view = () => html`
<ul>
${map(
list,
item =>
html`
<li id=${item.id}>${item.text}</li>
`

)}

</ul>
`
;

document.body.append(view());

setInterval(() => {
list([...list().sort(() => Math.random() - 0.5)]);
}, 1000);

Try it on Codesandbox

If you look closer in the web inspector you'll notice that most of the time not all the item elements will light up signifying a DOM operation. This is the diff engine at work and will keep your list rendering super snappy!