React

Licencia de Creative Commons mario@mariogl.com

Introducción a
React

React

Introducción

  • Librería JS

  • UI reactivas

  • SPA: Single Page Applications

  • Data binding

  • Web components

  • Microservicios / Jamstack

  • Código fuente y código compilado

  • JSX

React

Componentes

React

React

React

Microservicios

React

React

Jamstack

React

React

Jamstack

React

React

Jamstack

React

React

Entorno de desarrollo

React

Entorno de desarrollo

"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode"

React

Entorno de desarrollo

React

Node.js y npm

React

npm

  • Repositorio de paquetes distribuibles

  • La carpeta node_modules

  • El archivo package.json

React

Comandos npm

  • Instalar un paquete:
        npm install paquete [--save-dev]

  • Instalar todas las dependencias registradas:
        npm install

  • Instalar sólo las dependencias de producción:
        npm install --production

  • Ejecutar un paquete:
        npx ejecutable

React

Configuración proxy

npm config set proxy http://username:password@host:port

npm config set https-proxy http://username:password@host:port

Introducción a JavaScript

JavaScript - JSON

React

Conceptos iniciales

  • Interpretado, compilado y ejecutado en el navegador

  • Cada navegador programa su propio motor de JS

  • Estandarización: ECMAScript

  • La versión ES6 o ES2015

  • Transpiladores: Babel, TypeScript

  • Módulos:

    • import / export

    • webpack

React

ES6

  • let y const

React

let a = 3;

let a = 10;  // Error
var a = 12;  // Error

const b = 10;

b = 3; // Error

const obj = {
    x: 10,
    y: 12
}

obj.x = 15;  // OK

obj = {    // Error
    x: 15,
    y: 12
}

ES6

  • let y const

  • Template literals

React

let nombre = "Antonio";

let cuadrado = function(x) {
    return x * x;
}

let n = Math.floor(Math.random() * 10);

let saludo1 = "Hola, " + nombre + ". El cuadrado de " + n + " es " + cuadrado(n) + ".";
let saludo2 = `Hola, ${nombre}. El cuadrado de ${n} es ${cuadrado(n)}.`;

ES6

  • let y const

  • Template literals

  • for ... of

React

let nombres = ["Patricia", "Zacarías", "Miguel", "Maite"];

for (let i in nombres) {
    console.log(nombres[i]);
}

for (let nombre of nombres) {
    console.log(nombre);
}

let obj = {
    x: 3,
    y: 4
}

for (let i in obj) {
    console.log(obj[i]);
}

let nombre = "Antonio Jesús";

for (let c of nombre) {
    console.log(c);
}

ES6

  • let y const

  • Template literals

  • for ... of

  • Funciones

    • Parámetros por defecto

React

function potencia(x, y = 2) {
    return Math.pow(x, y);
}

console.log(`10 elevado a 8 es ${potencia(10, 8)}`);
console.log(`El cuadrado de 5 es ${potencia(5)}`);

ES6

  • let y const

  • Template literals

  • for ... of

  • Funciones

    • Parámetros por defecto

    • Función arrow:

      (parámetros) => expresión_devuelta

React

const potencia = function (x, y = 2) {
    return Math.pow(x, y);
}

const potencia = (x, y = 2) => Math.pow(x, y);

setTimeout(() => console.log("pausa"), 2000);

ES6

React

  • Operador spread

    • Parámetros en funciones

    • Copiar un array en otro

    • push inmutable

    • Copiar un objeto en otro

    • Mergear objetos

// function(a, b, c)
function sumar(a, b, c) {
  console.log(a + b + c);
}
let nums = [1, 3, 6];
sumar(...nums);

// function(n parámetros)
function sumar(...nums) {
  let suma = 0;
  for (n of nums) {
    suma += n;
  }
  console.log("La suma es " + suma);
}
let a = 3;
let b = 7;
let c = 8;
sumar(a, b, c);

// push y unshift
let nums1 = [1, 3, 6];
let nums2 = [0, 52, 15, 9];

nums1.push(...nums2);
console.log(nums1);
nums1.unshift(...nums2);
console.log(nums1);

// meter un array en medio de otro
let nums1 = [1, 3, 6];
let nums2 = [0, 52, 15, 9];
nums1.splice(1, 0, ...nums2);
console.log(nums1);

// copiar un array
let nums1 = [1, 3, 6];
let nums2 = [...nums1];

// copiar un objeto
let o1 = {
  x: 3,
  y: 5
}
let o2 = { ...o1 };

// mergear un objeto con defaults (ES2018)
let defaults = {
  ancho: 100,
  alto: 200,
  color: "rojo"
}

let o1 = {
  ancho: 200,
  grosor: 10000
}

o1 = { ...defaults, ...o1 };

React

Métodos de los arrays

  • Métodos:

    • map

let nombres = ["juan", "luisa", "amparo", "arturo"];

let nombresMays = nombres.map(nombre => nombre.toUpperCase());

console.log(nombresMays);

React

Métodos de los arrays

  • Métodos:

    • map

    • filter

let personas = [
    {
        nombre: "juan",
        edad: 15
    },
    {
        nombre: "luisa",
        edad: 35
    },
    {
        nombre: "amparo",
        edad: 17
    },
    {
        nombre: "arturo",
        edad: 32
    }
];

let mayoresEdad = personas.filter(persona => persona.edad >= 18);

console.log(mayoresEdad);

React

Métodos de los arrays

  • Métodos:

    • map

    • filter

    • reduce

let nums = [2, 4, 10, 15, 12];

let suma = nums.reduce((x, y) => x + y);

let objs = [
    {
        x: 3,
        y: 2
    },
    {
        x: 8,
        y: 10
    },
    {
        x: 10,
        y: 15
    }
]

let sumaX = objs.reduce((acc, obj) => acc + obj.x, 0);            // Método 1
let sumaX = objs.map(obj => obj.x).reduce((obj1, obj2) => obj1 + obj2);     // Método 2

React

Desestructuración

  • Asignar desde un array

  • Intercambiar variables

function medidasMueble(mueble) {
  // ...

  return [100, 70, 20];
}

let [ancho, alto, profundo] = medidasMueble(mesa);

console.log(ancho, alto, profundo);

// 100, 70, 20
let a = 10;
let b = 20;
 
[a, b] = [b, a];

console.log(a, b);

// 20, 10

React

Desestructuración

  • Asignar desde un array

  • Intercambiar variables

  • Asignar desde un objeto

function getRGB(colorHex) {
  // ...

  return {
    alias: 'deeppink',
    red: 255,
    green: 20,
    blue: 147,
    alpha: 0.8
  }
}

let { red, green, blue } = getRGB("#ff1493");

console.log(red, green, blue);

// 255, 20, 147
let personas = [{
  nombre: "Luis",
  apellido: "Herrera",
  edad: 23
},
{
  nombre: "Marta",
  apellido: "Nieto",
  edad: 29
}];
 
for (let {nombre, edad} of personas) {
  console.log(`Me llamo ${nombre} y tengo ${edad} años`);
}

// Me llamo Luis y tengo 23 años
// Me llamo Marta y tengo 29 años
let persona = {
  nombre: "Luis",
  edad: 23
}

let { nombre, edad, estado = "soltero" } = persona;

console.log(nombre, edad, estado);

// Luis, 23, soltero
let notas = {
  mat: 8,
  fis: 6,
  dib: 5,
  tec: 6
}

let { mat: matematicas, fis: fisica, dib: dibujo, tec: tecnologia } = notas;

console.log(matematicas, fisica, dibujo, tecnologia);

// 8, 6, 5, 6

React

Manipulación del DOM

  • El Document Object Model

<!DOCTYPE html>
<html lang="es-ES">

<head>
  <title>DOM</title>
  <script src="js/jquery.min.js"></script>
  <script src="js/scripts.js"></script>
  <link rel="stylesheet" href="css/estilos.css">
</head>

<body>
  <header>
    <h1>Ejemplo DOM</h1>
  </header>
  <div>
    <h2>Esto es un documento HTML</h2>
    <img src="img/html.jpg" alt="Documento HTML">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Non consectetur sapiente esse odit dolorem fugiat, iure
      omnis dolore obcaecati veniam necessitatibus sit quia praesentium, nesciunt suscipit. Adipisci illum tempore fuga.
    </p>
    <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Omnis, consequatur? Nostrum repudiandae qui expedita
      optio exercitationem sapiente rem, quisquam ipsam, sunt veniam dolorum architecto similique! Iusto quibusdam omnis
      tenetur nihil.</p>
  </div>
</body>

</html>

React

Manipulación del DOM

  • El Document Object Model

  • Nodos HTML

  • Propiedades de los nodos:

    • Genéricas:

      • classList

      • className

      • id

    • Particulares:

      • src

      • href

      • type

      • disabled

  <header class="cabecera titulo">
    <h1 id="titulo-pagina">Ejemplo DOM</h1>
  </header>
  <div>
    <h2>Esto es un documento HTML</h2>
    <img src="img/html.jpg" alt="Documento HTML">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Non <a href="https://consectetur.com">consectetur</a> sapiente esse odit dolorem fugiat, iure
      omnis dolore obcaecati veniam necessitatibus sit quia praesentium, nesciunt suscipit. Adipisci illum tempore fuga.
    </p>
    <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Omnis, consequatur? Nostrum repudiandae qui expedita
      optio exercitationem sapiente rem, quisquam ipsam, sunt veniam dolorum architecto similique! Iusto quibusdam omnis
      tenetur nihil.</p>
    <input type="text" placeholder="Introduce un valor">
    <button type="submit" disabled>
      Enviar
    </button>
  </div>

React

Manipulación del DOM

  • Eventos
  • Tipos de eventos
  • ​Cancelar la operación por defecto:
    • ​evento.preventDefault()
  • ​Quién ha emitido el evento:
    • ​evento.target

React

create-react-app

  • Crea el proyecto

  • react-scripts

  • eslint

  • webpack

  • servidor web de desarrollo

  • compila el código

React

Directorios

  • /src: código fuente para desarrollar la app, Webpack lo tomará como origen para crear todo el código final.

  • /public: archivos estáticos, Webpack no los procesará, simplemente los copiará en la carpeta de build.

  • /build: carpeta donde irá el código final de la app, generado por Webpack.

React

Despliegue

  • La carpeta build

  • Netlify

React

Componentes

  • Un tipo de elementos React

  • Componentes funcionales:

    • función

    • retorna elementos React

    • se exporta

React

JSX

  • Sintaxis que se parece a HTML pero es JavaScript

  • Atajo para no escribir la función React.createElement() 
  • Elementos React
  • Un solo padre
  • className, htmlFor
  • Etiquetas autocerradas
  • Expresiones JS dentro con { }
  • Condiciones

  • Bucles

  • Eventos

React

Componentes dentro de componentes

  • Etiqueta propia

  • props

  • children

  • propTypes (npm install prop-types)

    • componente.propTypes = {
          ...
      }

    • PropTypes.string, PropTypes.number, PropTypes.bool, PropTypes.arrayOf(), PropTypes.shape()

    • PropTypes.isRequired

React

El state

  • El hook useState()

  • Devuelve un array con [variable, setVariable]

  • React vigilará cambios en la variable y hará que la UI reaccione a ellos

  • No modifico nunca el valor de la variable directamente

  • Cada vez que se modifica el valor, se llama de nuevo al componente

React

Hooks básicos

  • useState(valorInicial)

    • Sirve para declarar una variable de estado.

    • Devuelve un array con [variable, setVariable].

  • useEffect(callback, dependencias)

    • Sirve para ejecutar una función sólo cuando cambie alguna de las dependencias.
    • No devuelve nada.
  • useRef(valor)
    • Sirve para declarar una variable sin que se redeclare en cada llamada al componente.
    • Devuelve un objeto con una propiedad current cuyo valor es el que le hemos pasado al hook.

React

Hooks básicos

  • useMemo(callback, dependencias)

    • Sirve para que se calcule un valor y se memorice, y sólo se vuelva a recalcular cuando cambie alguna de las dependencias.

    • Devuelve el valor calculado.

  • useCallback(callback, dependencias)

    • Sirve para memorizar una función y que se declare sólo una vez, excepto si cambia alguna de las dependencias.

    • Devuelve la función callback.

React

Formularios

  • Vincular cada control de formulario a una variable de estado, a partir de su propiedad value o checked, según el tipo de control.

  • Vincular el evento onChange de cada control a una función que modifique la variable del punto anterior a partir del e.target

<input
  type="text"
  id="nombre"
  name="nombre"
  value={formDatos.nombre}
  onChange={modificarDatos}
  required
/>
const modificarDatos = e => {
  const nombrePropiedad = e.target.name;
  setFormDatos({
    ...formDatos,
    [nombrePropiedad]: e.target.type === "checkbox" ? e.target.checked : e.target.value,
  });
};

React

Context

  • Permite poner un valor a disposición de un componente y todos sus descendientes sin tener que pasarlo por props.

  • Podemos pasar un objeto para poder poner varios valores a disposición de los componentes.

React

Context

  • Crear un contexto: createContext()

  • Consumir un valor de un contexto: useContext(NombreContext)

  • Colocar un proveedor de contexto englobando a otros componentes y proporcionando el valor:
    <NombreContext value={valor}>

// Crear un contexto
const NombreContexto = createContext();
// Consumir un valor de un contexto
const valor = useContext(NombreContexto);
// Englobar componentes con un proveedor de contexto
<NombreContexto.Provider value={valor}>
  <Componentes>...</Componentes>
</NombreContexto.Provider>

React

Reducers

  • Permiten aislar toda la lógica de modificación del estado

  • Funcionan mediante llamado de acciones

  • Las acciones son objetos

  • Las acciones se llaman mediante dispatch()

const datosReducer = (state, action) => {
	switch (action.type) {
		case "accion1":
			return stateModificado1;
		case "accion2":
			return stateModificado2;
		case "accion3":
			return stateModificado3;
		default:
			return state;
	}
}

React

Reducers

  • Usamos el hook useReducer para obtener el estado y la función dispatch.

const [state, dispatch] = useReducer(functionReductora, estadoInicial);

React

Enrutado

  • La librería react-router-dom

  • Toma el control de los links de navegación y hace que haya una página u otra en base a la URL, sin que se recargue la app

  • Haremos que cada página sea un componente

  • Vincularemos cada ruta con un componente

React

Enrutado

  • Englobaremos todo lo que queramos que esté controlado por el router en un componente BrowserRouter

  • Lo renombraremos a Router

// Al principio del archivo:
import { BrowserRouter as Router } from "react-router-dom";

// En el JSX:
<Router>
  <RestoDeComponentes>...</RestoDeComponentes>
</Router>

React

Enrutado

  • Usaremos los componentes Switch y Route para indicar qué componente se tiene que renderizar con cada ruta

  • También podemos establecer redirecciones con el componente Redirect

  • Las coincidencias se buscan por orden. Si se llega hasta el final es que no se ha encontrado ninguna coincidencia, por eso el 404 lo ponemos al final

<Switch>
  <Route path="/portada" exact>
    <Portada />
  </Route>
  <Route path="/listado" exact>
    <Listado />
  </Route>
  <Route path="/quienes-somos" exact>
    <QuienesSomos />
  </Route>
  <Route path="/" exact>
    <Redirect to="/portada" />
  </Route>
  <Route path="*" exact>
    <NotFound />
  </Route>
</Switch>

React

Enrutado

  • Podemos establecer rutas con parámetros:
    /factura/4
    /alumno/2737
    /bus/32

  • Para recoger los parámetros desde el componente usamos el hook useParams

<Switch>
  ...
  <Route path="/factura/:id" exact>
    <Factura />
  </Route>
  <Route path="/editar/:tipo/:id" exact>
    <FormFactura />
  </Route>
  ...
</Switch>
const Factura = () => {
  const { id } = useParams();
  return (
  	...
  )
}
const FormFactura = () => {
  const { tipo, id } = useParams();
  return (
  	...
  )
}

React

Enrutado

  • Podemos recoger los parámetros query con el hook useLocation

  • Devuelve un objeto con una propiedad search

  • Se utiliza la clase URLSearchParams de JavaScript para parsear el resultado

const FormFactura = () => {
  const { tipo, id } = useParams();
  const query = new URLSearchParams(useLocation().search);
  // query.get("dato") para obtener el parámetro query que queramos
  return (
  	...
  )
}

React

React

By mariogl

React

Curso React 14 junio - 1 julio 2021

  • 609