8. Librerias y Frameworks JS

Como último tema del módulo, veremos cómo reutilizar código o incluso una arquitectura para desarrollar aplicaciones web más rápido, con cierta complejidad y fáciles de mantener. Aprenderás a:

  1. Utilizar algún ejemplo de librerías javascript

  2. Conocer los elementos de la arquitectura Jamstack

  3. Usar React como ejemplo de framework web

Está organizado en 8 talleres de unas 3 sesiones de clase. En total unas 24 sesiones de clase más tu trabajo en casa.

La dedicación depende del conocimiento previo, motivación y capacidad de aprendizaje del estudiante para esa sesión en concreto.

8.1. Utilidad de las librerías JS

  1. Biblioteca (library): conjunto de funciones (y más cosas) reutilizables en tu código

  2. Usa la programación modular:

    1. Dividir en bloques pequeños

    2. Usando el patrón de diseño KISS

    3. Para compartir el código

  3. Librerías JS vs Frameworks Web vs Jamstack

    1. Una librería no es un framework

    2. Un framework usa, generalmente, librerías JS

    3. Jamstack es una arquitectura de la aplicación

      1. Javascript: como tecnología principal

      2. Apis: para implementar funcionalidad externa

      3. Markup: directo o para generar estáticamente (SSG), usando plantillas (frameworks web)

Actividad T08-A01. Tu biblioteca JS

Crea tu propia biblioteca JS (biblioteca.js), que podrías usar en diferentes sitios web. Por ejemplo, que tenga las siguientes funciones que ya hemos visto:

  1. Cálculo del IMC de una persona

  2. Función calculadora con la función como operador

  3. Suma a cada elemento de un array, un valor. Los dos se pasan por parámetro.

  4. Validación de un dni

  5. Validación de una matrícula española

8.2. Bibliotecas JS

  1. Hay un montón de bibliotecas JS

  2. Empezaron siempre como una biblioteca particular

  3. Cada día más útiles porque:

    1. Genera código de más calidad (profesional)

    2. Para cubrir necesidades específicas

    3. Permite desarrollar mucho más rápido

  4. Pero a un coste:

    1. Rendimiento

    2. Dependencia

  5. Un primer ejemplo: librerías para dibujar gráficos (ChartJS )

    1. Creas el componente donde irá el gráfico (elemento canvas en este caso porque usa el Canvas API)

    2. Añades la librería

    3. Usas la librería para dibujar el gráfico que te interesa (en este caso un diagrama de barras con los valores en el array data) usando el objeto Chart

      <div>
        <canvas id="myChart"></canvas>
      </div>
      
      <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
      
      <script>
        const ctx = document.getElementById('myChart');
      
        new Chart(ctx, {
            type: 'bar',
            data: {
                labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
                datasets: [{
                    label: '# of Votes',
                    data: [12, 19, 3, 5, 2, 3],
                    borderWidth: 1
                }]
            },
            options: {
                scales: {
                    y: {
                        beginAtZero: true
                    }
                }
            }
        });
      </script>
      

Actividad T08-A02. Dibujar dos gráficos en una página web

Crea una página web que contenga dos gráficos, dentro de un componente con su título h1 correspondientes (fuera del gráfico). Es decir, es una web no sólo con los dos gráficos, que tenga al menos algo de texto.

Los 2 graficos son:

  1. Un diagrama de barras con la cantidad de fruta que tenemos: 6 peras, 10 naranjas y 4 manzanas

  2. Un histórico de temperaturas para los 12 meses del año (te inventas las temperaturas de cada mes)

8.3. Librería de Geolocalización

  1. Leaflet permite la creación y uso de mapas interactivos

  2. Funciona en la web única y con un peso ligero (menos de 50 KB)

  3. Tiene multitud de funcionalidades:

    1. Para visualizar información: mapas, imágenes, puntos de interés, marcadores …

    2. Para interactuar con el mapa: desplazamiento por el mapa, de objetos, eventos …

    3. Para controlar el mapa: capas, zoom …

  4. Y es muy fácil de utilizar:

    var map = L.map('map').setView([51.505, -0.09], 13);
    
    L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
    
    L.marker([51.5, -0.09]).addTo(map)
      .bindPopup('A pretty CSS popup.<br> Easily customizable.')
      .openPopup();
    

Actividad T08-A03. Mi primer mapa con Leaflet

Crea una web que tenga un componente que se llame mi-mapa en el que cargues un mapa de Vigo (España) y coloques un marcador sobre la posición en la que el CPR DanielCastelao y que diga «Aquí estudio yo».

8.4. Leaflet Quick Start Guide

  1. Una guía paso a paso para conocer los elementos básicos

  2. Usa las «teselas» de openstreetmap

  3. Pasos a seguir:

    1. Incluyes la librería JS y la hoja de estilos CSS

    2. Defines el componente en el que irá el mapa (con un identificador y un tamaño)

    3. Defino el objeto mapa (posición y nivel de zoom, vía opciones o con setView)

    4. Añadimos información al mapa (podríamos tener varias capas y de diferentes orígenes). P.ej para capas raster usamos tileLayer

    5. Añades objetos sobre el mapa (por ejemplo Marker , Circle , Polygon )

    6. Puedes añadir mensajes a los objetos (PopUp )

  4. Además cada objeto tiene un conjunto de eventos:

    1. El evento se lanza cuando interactúa al usuario (hace zoom, pulsa sobre un objeto, …)

    2. Capturas el evento y le asignas una función

Actividad T08-A04. Mi primer mapa con Leaflet

Al mapa creado en la sesión anterior, le vas a añadir los siguientes requisitos:

  1. Le añades dos marcadores más

  2. Y un círculo de color azul

  3. Y un polígono de color verde

  4. Cada objeto tendrá un aviso (popup) que se abrirá cuando pulses en el objeto

  5. ¿Sabrías como añadir las «teselas» de Google Maps?

Además, ya que el mapa está en la web, vas a crear una lista (una especie de log) donde, cada vez que se pulse en un objeto o en un punto del mapa, quedará registrado. Por ejemplo:

  1. Pulsaste en el círculo

  2. Pulsaste en la posición X,Y (x, y las coordenadas de la posición)

  3. Pulsaste en el marcador

  4. … y así sucesivamente

8.5. El Framework React

  1. Biblioteca JS:

    1. Centrada en el Diseño UI Web (también con React Native para desarrollo móvil)

    2. Con datos que cambian continuamente («reacciona constantemente»)

    3. Lenguaje declarativo, sencillo y fácil de combinar (componer)

  2. Algunas características:

    1. Usa componentes: bloques con los que construyes tu interfaz

    2. Aunque opcional, usa el lenguaje de marcado JSX

    3. Usa un DOM Virtual (frente al real de la aplicación), para controlar los cambios

    4. Usa variables de estado para controlar cada elemento (visión instantánea del componente)

    5. Usa atributos (propiedades) para configurar cada componente

    6. Usa un ciclo de vida para el componente

    7. Es una librería con un fuerte paradigma funcional

      import { useState } from 'react';
      
      export default function MyApp() {
          const [count, setCount] = useState(0);
      
          function handleClick() {
              setCount(count + 1);
          }
      
          return (
                  <div>
                  <h1>Counters that update together</h1>
                  <MyButton count={count} onClick={handleClick} />
                  <MyButton count={count} onClick={handleClick} />
                  </div>
          );
      }
      
      function MyButton({ count, onClick }) {
      return (
      <button onClick={onClick}>
      Clicked {count} times
      </button>
      );
      }
      
  3. Permite realizar aplicaciones realmente complejas (vamos a ver sólo lo más básico)

  4. Tu primer componente

    1. Defines un componente (es una función que devuelve HTML o JSX)

    2. Que exportas para poder reutilizarlo

    3. Y luego lo usas como si fuera una nueva etiqueta HTML (la primera letra en mayúsculas y con cierre)

    4. Construyes tu aplicación con diferentes componentes

Actividad T08-A05. Tu primera interfaz con React

Para el despliegue de la aplicación usas el editor en línea del tutorial (tiene un editor y visualizador integrado).

  1. Diseño de componentes:

    1. Crea un componente que devuelva la cadena de texto «Hola Mundo»

    2. Crea un componente (como el ejemplo Profile) que devuelva una imagen

    3. Crea un componente que sea una lista de tres elementos

  2. Diseño de tu aplicación:

    1. Mostrará un título h1 que sea «Ejemplo de Aplicación»

    2. Y después una imagen, con un texto debajo que diga «Hola Mundo»

    3. Y lo repites dos veces más. La última no llevará el texto que dice Hola Mundo

8.6. Describir la Interfaz

  1. Escribir con JSX

    1. Devuelve un sólo nodo raíz (del que dependen todos los elementos)

    2. Si no hay un div, usas etiquetas vacías

    3. Todas las etiquetas han de cerrarse

    4. Recuerda que es lo que devuelve tu componente

  2. En JSX puedes usar expresiones JS usando llaves

    1. Puede definir variables (o expresiones)

    2. Y luego usarlas dentro del etiquetado JSX

    3. Un objeto (JSON) es una variable también (puede ser confuso las dobles llaves)

  3. Puedes usar «argumentos» en los componentes (props)

    1. Son los «atributos» que le pasas a las etiquetas JSX (que pueden ser elementos HTML o componentes)

    2. A su vez, un componente los puede usar. Es decir, un hijo puede leer esos valores (props) del componente padre

    3. Permiten añadir personalización de los componentes usando «atributos» (propiedades)

      import { getImageUrl } from './utils.js';
      
      function Avatar({ person, size }) {
        return (
          <img
            className="avatar"
            src={getImageUrl(person)}
            alt={person.name}
            width={size}
            height={size}
          />
        );
      };
      
      export default function Profile() {
        return (
          <div>
            <Avatar
              size={100}
              person={{
                name: 'Katsuko Saruhashi',
                imageId: 'YfeOqp2'
              }}
            />
            <Avatar
              size={80}
              person={{
                name: 'Aklilu Lemma',
                imageId: 'OKS67lh'
              }}
            />
            <Avatar
              size={50}
              person={{
                name: 'Lin Lanying',
                imageId: '1bX5QH6'
              }}
            />
          </div>
        );
      };
      

Actividad T08-A06. Describiendo la interfaz

Refactoriza la aplicación de la clase anterior usando props, es decir, los componentes permitirán escribir texto diferente y url diferente para la imagen.

Añade un componente con una lista de 5 frutas (que estarán en una lista/array)

8.7. Programando la Interfaz

  1. Puedes usar if/then/else o el operador ternario ?::

  2. La lógica se hace en JS, pero está insertada en JSX (que devuelves en el componente)

  3. Puedes usar arrays y programación funcional en el renderizado (por ejemplo con listas ):

    1. Creas un array (simple o un array de objetos)

    2. Creas un conjunto de nodos JSX usando el array (con la funcion map)

    3. Usas ese nuevo array (de elementos JSX) en tu componente

      const people = [
              'Creola Katherine Johnson: mathematician',
              'Mario José Molina-Pasquel Henríquez: chemist',
              'Mohammad Abdus Salam: physicist',
              'Percy Lavon Julian: chemist',
              'Subrahmanyan Chandrasekhar: astrophysicist'
      ];
      
      export default function List() {
          const listItems = people.map(person =>
                <li>{person}</li>
          );
          return <ul>{listItems}</ul>;
      };
      
    4. En la creación del array puedes usar objetos y filtrarlos usando el método filter() de un array

    5. Cada elemento de un array necesita tener un identificador único (key)

Actividad T08-A07. Programando la interfaz

Crea una lista con 5 frutas que tienes en un array. Las frutas cuyo nombre tenga más de 5 caracteres, aparecerán en negrita

8.8. Agregando Interactividad

  1. Puedes usar tu manejador para responder a eventos en JSX

    1. Usas tu función como una prop del componente

    2. Defines la función dentro del componente (o como función anónima en el evento JSX)

      function AlertButton({ message, children }) {
         return (
             <button onClick={() => alert(message)}>
                 {children}
             </button>
         );
      };
      
      export default function Toolbar() {
         return (
             <div>
                <AlertButton message="¡Reproduciendo!">
                   Reproducir película
                </AlertButton>
                <AlertButton message="¡Subiendo!">
                   Subir imagen
                </AlertButton>
             </div>
         );
      };
      
  2. La memoria de un componente se llama estado (y se puede gestionar)

    1. Necesitamos guardar el estado (tener memoria de lo que ocurre en el componente)

    2. Para eso usamos variables de estado

    3. Que se definen usando una función especial (hook) llamada useState

    4. Se pueden definir más de una variable de estado

      // Es necesario importar la función especial (hook), en este caso useState
      import { useState } from 'react';
      (...)
      // useState devuelve un array con dos valores (el estado  inicial y la función que actualizará esa variable de estado
      const [index, setIndex] = useState(0);
      

Actividad T08-A08. Programando la interfaz

Tienes una BD de usuarios en el archivo usuario.json . Tiene 5 usuarios, con nombre, apellidos y edad de cada uno

Desarrolla una aplicación que muestre el detalle de un usuario, con un botón que permite avanzar. Añade otro botón que te permita retroceder.