Skip to content

Reactive if() and $repeat()

INFO

$if() and $repeat() are methods, used in the Template Tree.

WARNING

On reactive changes, $if() and $repeat() are always re-rendering the DOM elements!

if()

The first argument in $if() is the condition, which can be boolean value, or a function, returning boolean value. When a state is used in that function, $if() becomes reactive.

WARNING

On reactive changes, $if() is always re-rendering the DOM elements!

js
import { compose, state, template } from 'paintor'

const MyComponent = function() {
  return template((x) => {
    const myState = state({ pass: true })
    let counter = 0

    const ifHandler = () => {
      x.div({ style: { color: 'green' }}, counter++)
    }
    const elseHandler = () => {
      x.div({ style: { color: 'red' }}, counter++)
    }

    x.div(
      x.$if(
        () => myState.pass, // Condition
        ifHandler, // Runs on true
        elseHandler // Runs on false
      )
    )

    setInterval(() => {
      // Reverse
      myState.pass = !myState.pass
    }, 1000)
  })
}

compose(MyComponent()).paint('#reactive-if')
html
<div id="reactive-if"></div>
example

$repeat()

The first two arguments in $repeat() are from and to. They both accept integer values, or functions, returning integer values. When states are used in these functions, they become reactive.

from and to are both inclusive. For example, if both are 0, the handler will still be called once. However, if from or to is NaN (or a function, returning NaN), the loop will be empty.

WARNING

On reactive changes, $repeat() is always re-rendering the DOM elements!

js
import { compose, state, template } from 'paintor'

const MyComponent = function() {
  return template((x) => {
    const myState = state({ from: 1, to: NaN })

    // "from" label and button
    x.label('from')
    x.input({
      type: 'number',
      value: myState.from,
      onChange: (event) => (myState.from = event.target.value)
    })

    // "to" label and button
    x.label('to')
    x.input({
      type: 'number',
      value: myState.to,
      onChange: (event) => (myState.to = event.target.value)
    })

    // Result
    x.div({ id: 'elements-container' },
      x.$repeat(
        () => myState.from,
        () => myState.to,
        (index) => {
          x.div(index)
        }
      )
    )
  })
}

compose(MyComponent()).paint('#reactive-repeat')
html
<div id="reactive-repeat"></div>
example

Hint: Change the numbers in the inputs.