> Manuales > Manual de Polymer 2

Primeros pasos con polymer-redux, la librería para facilitar el trabajo con Redux desde aplicaciones y componentes escritos con Polymer.

"Polymer Redux" nos permite trabajar con Redux de una manera ágil, ya que nos ofrece una serie de mixins que ahorran escribir bastante código y nos aíslan de ciertas complejidades del uso de este patrón de desarrollo de software para gestión de los datos.

Esta librería está disponible desde Polymer 1.x, aunque en ese momento se implementaba por medio de behaviors. En las nuevas versiones de Polymer, de la 2 en adelante, los behaviors se han sustituido por mixins, que se apoyan en las características de orientación a objetos de Javascript ES6. Por supuesto, en este artículo nos centraremos más en la nueva versión de Polymer Redux, que podremos usar en el desarrollo actual.

Vamos a dar por entendidos diversos conocimientos básicos de Redux, por lo que, si alguien no conoce las generalidades de Redux, sería importante leer antes el artículo de DesarrolloWeb donde hablamos de Redux en general.

Mediante Polymer Redux conseguimos agilizar el trabajo principalmente de dos áreas:

Primeros pasos para implementar Polymer-Redux

A continuación vamos a explicar de manera práctica cómo comenzar con Polymer Redux, en el marco en una aplicación sencilla. Como sabemos, podemos crear una aplicación vacía con el CLI de Polymer. Eso lo dejamos de tu parte, nosotros nos centraremos en las cosas que tienen que ver con Redux.

El primer paso será instalar Polymer Redux y sus dependencias.

Polymer Redux está implementada encima de la propia librería Redux, la "oficial", que podemos usar en cualquier proyecto Javascript en general. Por tanto, tenemos que comenzar por instalarla.

npm install redux

Luego, tendremos que instalar Polymer Redux en particular. Este es el comando de instalación con Bower, aunque próximamente en Polymer 3 la instalaremos con npm.

bower install polymer-redux

Creación del archivo para el Redux Mixin

Una vez instaladas las correspondientes librerías, vamos a crear un archivo llamado redux-mixin.html (o como lo quieras llamar) que será un mixin nuestro, en el que implementaremos las cosas necesarias para trabajar con Redux desde cualquier componente.

En este archivo comenzaremos instalando las dependencias necesarias para trabajar.

<script src="../../node_modules/redux/dist/redux.js"></script>
<link rel="import" href="../../bower_components/polymer-redux/polymer-redux.html">

En la primera línea hemos incluido el script de Redux genérico y en la segunda línea estamos trayendo la librería Polymer-Redux.

Creación del store

A continuación vamos a seguir trabajando sobre el archivo anterior redux-mixin.html, para escribir el correspondiente mixin, que nos servirá para implementar soporte a Redux en los componentes. En este archivo tenemos que realizar dos pasos fundamentales:

Podríamos decir que el store es el corazón de Redux. Nos permite almacenar el estado de la aplicación y distribuirlo allá donde se necesite acceder a él. Así que comenzaremos implementando dicho store, para lo cual usaremos la librería de Redux, ya que es algo que tiene que ver con ella más que con el propio Polymer.

Para crear el store necesitamos definir un estado inicial:

// Creamos el store
const estadoInicial = {
  msg: 'Hola Mundo'
};

Luego necesitamos implementar un reducer, que es la función que procesa las actions para manipulación del estado. De momento vamos a crear un reducer sencillamente vacío, que recibe el store y devuelve el mismo store sin modificar.

const reducer = (state) => state;
Nota: Obviamente no es el reducer con el que nos quedaremos al final en nuestra aplicación, pero nos sirve para comenzar, ya que todavía no tenemos acciones que manipulen nada.

Creamos el store con el método createStore(), que depende directamente de la librería de Redux genérica. De momento no hay nada específico de Polymer.

const store = Redux.createStore(reducer, estadoInicial);

Crear el mixin específico para implementar el store en la aplicación Polymer

Ahora que tenemos el store, sí que vamos a implementar algo específico de la aplicación Polymer: la creación del Redux mixin. Es un paso muy sencillo gracias a la librería polymer-redux.

ReduxMixin = PolymerRedux(store);

Resumen de la implementación del store y el mixin

Hasta este punto tenemos una aplicación vacía, en la que se encuentra la implementación del corazón de nuestro patrón Redux. Puedes haber organizado el código de tus carpetas de muchas maneras, pero en mi caso tengo lo siguiente.

El archivo de las dependencias contiene el script de redux.js y el import de polymer-redux que hemos visto antes.

El archivo de redux-mixin.html contiene el código de creación del store que nos quedará más o menos así.

<link rel="import" href="./redux-dependencies.html">

<script>
    const estadoInicial = {
      msg: 'Hola Mundo'
    };

    const reducer = (state) => state;
    const store = Redux.createStore(reducer, estadoInicial);
    ReduxMixin = PolymerRedux(store);
</script>

Crear un componente que accede a datos del store

El siguiente paso sería crear nuestro primer binding con los datos del store. Aquí nos ayudará bastante el mixin que acabamos de realizar, pues simplifica mucho el proceso de suscripción a los cambios del store.

Crearemos un componente cualquiera, teniendo especial cuidado para no olvidarnos de implementar el mixin que se ha realizado anteriormente.

class VisualizarMensaje extends ReduxMixin(Polymer.Element) {
// ...

En este componente crearemos una propiedad que asociaremos a una sección del store. El mecanismo de creación de la propiedad es el mismo que se usa habitualmente en Polymer, aunque ahora, gracias a la librería Polymer-Redux, podemos definir la parte del store a la que nos deseamos suscribir. Ese aspecto se configura mediante un valor de la propiedad llamado "statePath".

static get properties() {
  return {
    msg: {
      type: String,
      statePath: 'msg'
    }
  };
}

En statePath indicamos la ruta del store que corresponda. En este caso "msg" es la propiedad del store que nos interesaba. Pero imaginemos que queremos suscribirnos a una subpropiedad, para lo que se escribiría "propiedad.subpropiedad". O a la primera casilla de un array "miArray.0".

Ahora podemos usar esta propiedad como de costumbre, bindeando al template, o haciendo cualquier otro objetivo que nosotros tengamos. Cada vez que cambie el dato en el store, el nuevo valor llegará al componente, actualizando el valor de la propiedad.

Crear un componente que actualiza el store

Para acabar nuestro "hola mundo" con Polymer Redux vamos a crear un segundo componente para actualizar el store.

Recuerda que cualquier actualización del store se puede realizar por una "action", que se debe tratar en el correspondiente reducer.

Por tanto, en este caso tendremos que crear el reducer para tratar la acción y luego el componente que escale la acción.

Crear un reducer que implemente una acción

Esta parte no es algo específico de Polymer, sino de Redux. Tenemos que crear la función de nuestro reducer, en el ReduxMixin, con un código que podría parecerse a esto:

const reducer = (state, action) => {
  switch (action.type) {
    case 'UPDATE_MSG':
      return Object.assign( {}, state, { msg: action.texto} );
    default:
      return state;
  }
};

Como habitualmente, se usa un switch en el que tendremos un case para cada action. Nuestro action es de type "UPDATE_MSG". En esta acción recibimos un dato, que es el propio texto que se asignará a la propiedad "msg".

Nota: Recuerda que el state, cada vez que se actualiza el store, debe ser un objeto nuevo, creado desde cero. Por eso usamos el método Object.assign(). El nuevo state se entrega como valor de devolución del reducer.

Crear un componente que lanza una acción

Todos los componentes que implementan ReduxMixin tienen un método nuevo, llamado dispatch(), en el que enviamos la acción que debe llegar al store.

Así pues, en nuestro componente comenzaremos declarando que vamos a usar el mixin.

class ActualizarMensaje extends ReduxMixin(Polymer.Element) {
// ...

En este componente tendremos alguna interfaz para recibir un nuevo mensaje. Esta parte la harás como te parezca mejor. Podríamos tener por ejemplo en nuestro template un campo input y un botón.

<input type="text" id="texto">
<button on-click="actualizar">Actualizar mensaje</button>

Al hacer clic sobre el botón tenemos que enviar el nuevo valor en la action. El botón tiene un manejador de evento "click" que ejecuta el método actualizar(), cuyo código podemos ver a continuación.

actualizar() {
  this.dispatch({
    type: 'UPDATE_MSG',
    texto: this.$.texto.value
  });
}

Como puedes ver, todo es bastante sencillo. Al ejecutarse actualizar se invoca el método dispatch, al que se le envía el contenido de la acción, con su tipo y cualquier otro dato adicional que se necesite enviar al reducer.

Con esto en principio tendríamos todo lo que nos hace falta para actualizar los datos del store. Al ejecutarse este action en el reducer se producirá el cambio en el estado y por tanto se bindeará el nuevo valor al primer componente, con lo que se actualizará el mensaje.

Ahora sólo nos faltaría montar los componentes en la aplicación y así terminar nuestro primer ejemplo de Redux en Polymer.

Conclusión

Hemos visto solo una primera aproximación a Redux sobre Polymer. Detrás de Redux y de Polymer-Redux hay muchas otras posibilidades que seguro que tendrás que usar en tus aplicaciones, pero esperamos que con este tutorial te resulte más sencillo comenzar.

En el futuro realizaremos otros ejemplos más complejos de Redux con Polymer, pero mientras tanto te recomendamos la lectura de la documentación de la librería polymer-redux, https://tur-nr.github.io/polymer-redux/docs pues encontrarás mucha otra información de utilidad.

Además, si te interesa aprender de manera guiada te recomiendo también la clase que impartí sobre Redux y Polymer en el Curso de Polymer y Progressive Web Apps. Con más de dos horas de duración en la que se vieron diversos ejemplos que te ayudarán a entender casi todas las cosas que te ofrece la librería Polymer Redux en el contexto de las aplicaciones Polymer.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual