@composi/runtime:

Suscripciones

Efectos al Iniciarse

Cuando cubrimos init, se explicó cómo se podía ejecutar un efecto al iniciar un programa tan solo por pasarlo como un segundo valor en la tupla que devuelve init. En general, los efectos que se ejecutan en el inicio se conocen como suscripciones. Podemos ser más explícito sobre la implementación de una suscripción utilizando el método subscriptions en un programa. Esto debe devolver el efecto que ejecutar.

Las suscripciones sirven para detectar los movimientos del ratón, el pulsar del teclado, los cambios de la locación del navegador o para iniciar bucles.

function empezarContar() {
  let cuenta = 0
  const id = setInterval(() => {
    if (cuenta === 10) clearInterval(id)
    cuenta += 1
    programa.send(cuenta)
  }, 1000)
}
const programa = {
  init() {
    return estado
  },
  view(estado, send) {
    return render(

La cuenta es: {estado}.

, document.body) }, update(estado, mensaje, send) { if (mensaje) { // Fija el estado del programa con el valor del mensaje: return mensaje } }, subscriptions(send, getState) { return empezarContar(send, getState) } }

No hay nada de magia aquí. Las suscripciones hacen lo que dice la etiqueta. Usar suscripciones para ejecutar efectos al inicio es más explícito. Pero puedes usar cualquier método, init o subscriptions, para ejecutar efectos al inicio. Subscriptions reciben las funciones send y getState. Esto quiere decir que puedes acceder al estado actual del program or enviar un mensage a la function update desde una suscripción mediante estas funciones.

Tanto send como getState son opcionales. Si no vas a acceder al estado dentro de una suscripción, no hay que proveer getState como argumento. Si una suscripción no va enviar un mensaje, no se necesita el argument send:

const program = {
  init() {

  },
  view(estado, send) {

  },
  update(estado, mensaje, send) {

  },
  // getState y send son opcionales aquí:
  subscriptions(send, getState) {

  }
}

Atención: Las suscripciones no son para manipular el estado. El acto de cambiar el estado en un efecto resultará en que la vista y el estado estarán desincronizados. Si has producido algunos dataos en una suscripción y quieres actualizar el estado con ellos, hazlo por enviar un mensaje a una acción. Haciendo esto logrará que el algoritmo de reconciliación se ejecute, lo cual puede causar que la vista vuelva a rendirse.

Suscripciones Combinadas

Al igual que con cualquier otros efectos, puedes usar batch para ejecutar múltiples efectos al mismo tiempo. Consulte la documentación de efectos para ver cómo hacer esto.

Ahora bien, vamos a ver cómo usar suscripciones en tanda, o más bien, combinados. Vamos a tomar dos efectos, uno para conseguir datos y otro para iniciar un evento para escuchar la pulsación de teclas. Queremos que estos do se executen cuando el programa se inicia. Puesto que se trata de dos efectos, en vez de ponerlos directamente in el método subscriptions del program, los vamos a mantener aparte y usar una versión combinada. Puesto que vamos a conseguir los datos después de que el programa se inicie, no habrá estado para la rendición inicial del la vista. Así pues, tenemos que chequear si el estado es veraz o falso antes de retornar la rendición de la vista. Por eso, vamos a designar el estatdo inicial in el método init cómo null.

// Crear una unión etiquetada para el mensaje:
const Msg = union('usarLosDatosRecibidos')

// Aquí hay dos efectos.
// Cada efecto espera la función `send` como su argumento.
// Ésta será proveída automáticamente cuando los efectos en tanda se procesan.

// Efecto para consequir datos:
function fetchState(send, getState) {
  (async () => {
    const response = await fetch('/src/js/state.json')
    const data = await response.json()
    send(Msg.usarLosDatosRecibidos(data))
  })()
}
// Efecto para manejar la compresión de la tecla Enter:
function handleEnter(send, getState) {
  document.addEventListener('keypress', e => {
    if (e.keyCode === 13) {
      send(Msg.addItem())
    }
  })
}

// Combinar los efectos en uno:
const batchedSubscriptions = batch(fetchState, handleEnter)

// Definir el program que usar:
const program = {
  init() {
    // Aquí designamos el estado como null:
    return null
  },
  view(state, send) {
    // Aquí chequeamos si el estado es veraz o no:
    return state && render(, 'section')
  },
  update(state, msg, send) {
    const prevState = clone(state)
    return actions(prevState, msg)
  },
  subscriptions(send, getState) {
    // Aquí retornamos los efectos combinados.
    // No tenemos que invocar esto, solo lo retornamos.
    return batchedSubscriptions(send, getState)
  }
}

Abreviatura Para Suscriptions

Puedes usar el término subs en vez de subscriptions. Es más corto:

const programa = {
  init() {
    return estado
  },
  view(estado, send) {
    return render(

La cuenta es: {estado}.

, document.body) }, update(estado, mensaje, send) { if (mensaje) { // Fija el estado del programa con el valor del mensaje: return mensaje } }, subs(send, getState) { return empezarContar(send, getState) } }