Utilitário de repetição

O utilitário repeat é a forma recomendada pelo Markup para renderizar dados iteráveis ou conteúdo repetido. Ele lida com coisas como cache e rastreamento do modelo, garantindo que as alterações na lista aconteçam apenas nos itens que precisam delas.

javascript
html`${repeat(todos, renderTodo)}`

Por que usar repetir?

Os modelos Markup já lidam com arrays, mas como qualquer outro valor injetado, o Markup rastreia tudo e não seus itens individuais.

javascript
const [todos, updateTodos] = state([])

html`${() => todos().map(renderTodo)}`.render(document.body)

updateTodos((prev) => [
    ...prev,
    {
        name: 'Go to gym',
        status: 'pending',
    },
])

O código acima funcionará perfeitamente no que diz respeito à renderização de uma lista. O problema fica evidente quando um único item é alterado, adicionado ou removido. Isso ocorre porque a função será chamada novamente, gerando uma nova lista de conteúdo para renderizar. Se Markup vir uma nova lista, ele renderizará tudo novamente.

A melhor maneira é não mapear dinamicamente a lista na renderização, mas na criação, para que o Markup sempre tenha as coisas que deseja renderizar para que possa verificar se é diferente de antes ou não.

javascript
const [todos, updateTodos] = state([])

html`${todos}`.render(document.body)

updateTodos((prev) => [
    ...prev,
    renderTodo({
        name: 'Go to gym',
        status: 'pending',
    }),
])

Isso é exatamente o que o utilitário repeat faz por você, apenas pegando os dados e a função de renderização.

Números

O auxiliar repeat aceita um número entre muitas coisas. Este número representa o número de vezes que você deseja que a função de renderização de retorno de chamada precise ser chamada.

javascript
html`${repeat(3, html`<spa></span>`)}`

A função de retorno de chamada será chamada com números de 1 até o número que você forneceu junto com os índices.

javascript
html`${repeat(3, (n, index) => html`<spa>${n} - ${index}</span>`)}`.render(
    document.body
)
// <span>1 - 0</span><span>2 - 1</span><span>3 - 2</span>

Iteráveis e literais de objeto

Além disso, repeat pode consumir qualquer Object literal ou objeto iterável e isso inclui:

javascript
const iterable = {}

iterable[Symbol.iterator] = function* () {
    yield 1
    yield 2
    yield 3
}

html`${repeat(iterable, renderItem)}`

Como o modelo Markup não processa a renderização de tais objetos (exceto Array), esta é uma vantagem adicional no uso de repeat. Você não precisa se preocupar em converter nenhum dado em Array apenas para poder iterar e renderizar.

A função de retorno de chamada sempre será chamada com as entradas e o índice.

javascript
const employeesSalary = {
    'john doe': 30000,
    'jane doe': 54000,
}

html`${repeat(employeesSalary, ([name, salary], index) => html`...`)}`

Estado vazio

O repeat também consome um terceiro argumento opcional que é uma função que será chamada para retornar o que renderizar quando os dados estiverem vazios.

javascript
html`${repeat(todos, renderTodo, () => html`<p>No todos yet!</p>`)}`

Chaves e opções

Por padrão, repeat usa os próprios itens da lista como chaves de identidade para rastrear atualizações. Se seus itens são objetos ou você deseja rastreá-los por um identificador exclusivo, você pode passar um objeto de opções como terceiro argumento:

javascript
const options = {
    key: (todo, index) => todo.id,
    empty: () => html`<p>No todos yet!</p>`,
}

html`${repeat(todos, renderTodo, options)}`

O objeto de opções oferece suporte às seguintes propriedades:

Renderização de lista preguiçosa

Para otimizar listas com um grande número de itens complexos, você pode combinar o utilitário repeat com o utilitário visible. Isso adia a renderização dos itens da lista fora da tela até que eles estejam prestes a serem exibidos:

javascript
import { html, repeat, visible } from '@beforesemicolon/markup'

html`
    <ul>
        ${repeat(
            todos,
            (todo, index) =>
                visible(
                    () => html`<todo-item item="${todo}"></todo-item>`,
                    html`<li class="placeholder">Loading...</li>`,
                    { eager: index < 10 } // render first 10 immediately
                ),
            { key: (todo) => todo.id }
        )}
    </ul>
`
editar este documento