Skip to content

r-for Directive

r-for renders repeated template instances from arrays, iterables, and object-like values.

<li r-for="item in items">{{ item }}</li>

You can use in or of:

<li r-for="item of items">{{ item }}</li>

Use #-prefixed variable for index:

<li r-for="(item, #i) in items">{{ i }} - {{ item }}</li>

Object iteration is supported:

<li r-for="(key, value) in person">{{ key }}: {{ value }}</li>

Destructuring is supported:

<li r-for="{ name, age }, #i in users">{{ i }} - {{ name }} ({{ age }})</li>

Any valid expression can provide iterable data:

<ul>
<li r-for="n in numbers.filter((n) => n > 5)">{{ n }}</li>
</ul>

For stable identity and predictable updates, set a key on repeated nodes.

<li r-for="row in rows" :key="row.id" r-text="row.name"></li>

Important behavior in Regor templates:

  1. key="row.id" and :key="row.id" are both expression-based for list keying.
  2. Nested key paths are supported, including a.b.c.d.
  3. Use stable, unique keys from your domain model.

If keys are unstable, DOM reuse quality degrades and updates become less predictable.

r-for supports native table structures and component-based rows/cells.

<table>
<tbody>
<TableRow r-for="row in rows" :row="row" />
</tbody>
</table>
const tableCell = defineComponent(html`<td><span>{{ value }}</span></td>`, {
props: ['value'],
})
const tableRow = defineComponent(
html`<tr>
<TableCell :value="row.name" />
<TableCell :value="row.age" />
</tr>`,
{ props: ['row'] },
)
  1. Keep row templates minimal.
  2. Use stable keying.
  3. Avoid expensive per-row expressions in large lists.
  4. Prefer pagination/windowing for very large data sets.
  1. r-if
  2. r-bind
  3. r-text