React — Primeros pasos…
Temario
- Introducción
- ¿Qué es React?
- Componentes
- Document Object Model (DOM) y Virtual DOM (VDOM)
- JavaScript XML (JSX) — (Nuestro primer código en React, Variables y expresiones, atributos, Actualizando un elemento)
- Componentes en React (Funcionales y de Clase, Nuestro primer componente, Composición de componentes)
- Nuestra primer App
i. Introducción
Bienvenido a la primera Story (seguramente de muchas) de React… la idea es comenzar CASI desde cero, digo “CASI desde cero”, ya que es necesario tener conocimiento en JavaScript (Si no tienes idea, puedes darte una vuelta por aca [ref], y seguir todas las stories que he creado para aprender y comprender JavaScript), al menos de la edición de ES6 en adelante, también recomiendo ver esta otra Story[ref], ya que desde mi punto de vista es muy importante entender y comprender (al menos de manera básica) conceptos como Node.js, Yarn, Webpack, entre otros…
Conocimientos básicos:
- HTML, CSS3, JavaScript ES6+
Tener instalado:
- El entorno de ejecución Node.js[ref]
- Para los ejemplos vamos a usar Yarn[ref], pero puedes usar NPX[ref]
- Tu editor de código favorito, en mi caso estaré usando Visual Code[ref]
Y eso es todo!!!, así que comencemos…
ii. ¿Qué es React?
Antes de saber que es React, te recomiendo que leas la siguiente story: “Interfaz de usuario (UI), Experiencia de usuario (UX) y un poco más allá…”[ref].
Un poco de historia: React[ref] fue creado por Jordan Walke, un ingeniero de software en Facebook, que lanzó un prototipo inicial de React llamado FaxJS; fuertemente influenciado por XHP[ref][ref], una biblioteca de componentes HTML para PHP, la primera vez que se utilizó fue en las noticias de Facebook en el 2011, después en Instragram en el 2012 y liberado (código abierto) en el 2013. En el 2015 Facebook presenta React Native[ref], nos va a permitir el desarrollo nativo de Android, iOS y UWP. En el 2017 Facebook presenta React Fiber, es un algoritmo para consumir interfaces de usuario, que más tarde se convertiría en la base de React. De las últimas actualizaciones, quizás una de las más importantes es en el 2019, donde introduce Hooks (que ya veremos más adelante).
La página oficial, dice que:
React es una biblioteca de JavaScript para construir interfaces de usuario[ref].
Esto quiere decir que React nos va a ayudar a crear aplicaciones web interactivas compuestas, mediante pequeñas y aisladas piezas de código llamadas componentes; React se encargará de actualizar y renderizar de manera eficiente los componentes correctos cuando los datos cambien.
En la definición de arriba, hay un concepto muy importante “componentes”…
iii. Componentes
Si has usado HTML, imagina a los componentes como etiquetas personalizadas, pero con la ventaja de re-utilizarlos en cualquier parte de nuestra aplicación, veamos la siguiente imagen:
Así que, desde ahora en adelante, debemos de ir pensando toda la aplicación como componentes, lo primero, será dividir y descomponer el diseño de interfaz en unidades pequeñas y aisladas, donde cada una de las unidades pueda representarse como un componente, con la finalidad de poder agregarlo a otros componentes o a la aplicación web, hasta formar una interfaz gráfica compleja.
iv. Document Object Model (DOM) y Virtual DOM (VDOM)
Sabemos que el DOM (Document Object Model) es una interfaz que permite a JavaScript leer y manipular el contenido de un documento HTML.
Cada vez que se carga en el navegador un documento HTML, se crea un DOM correspondiente a esa página (Aplicación de página única (SPA)[ref]), donde creará un árbol de contenido, básicamente es convertir las etiquetas en nodos DOM.
Veamos como funciona por detrás el DOM:
- El motor del renderizado del navegador comenzará a analizar el documento HTML.
- Convertirá cada una de las etiquetas en nodos DOM, en forma de árbol llamado árbol de contenido.
- Analizará los estilos, tanto internos como externos (CSS), donde creará otro árbol llamado árbol de renderizado, este solo son rectángulos con atributos visuales (color, tamaño).
- Después cada uno de los nodos empezará a aparecer en pantalla, donde cada uno tendrá sus propiedades visuales.
Y con esto, le va permitir a JavaScript poder manipular dinámicamente el DOM. Al manipular todo el DOM, tenemos una gran desventaja, el navegador necesita recalcular la página completa (debe realizar todos los pasos anteriores), cada vez que sufre algún cambio, por lo que se vuelve muy lento, y no olvidemos que el motor de nuestro navegador de JavaScript, solo tiene un solo subproceso[ref].
Aquí es donde llega al rescate el DOM Virtual (VDOM), que como su nombre lo indica es una REPRESENTACIÓN VIRTUAL del DOM real que se mantiene en memoria, y en sincronía con el DOM real, mediante alguna biblioteca (en el caso de React es ReactDOM[ref]).
Veamos como funciona por detrás VDOM:
- Cada vez que nosotros agregamos un componente a la interfaz del usuario, se va a crear un DOM Virtual (gracias a ReactDOM).
- Cuando se manipula el componente (cambia su estado), en este caso ReactDOM vuelve a crear nuestro componente y lo mantiene en memoria.
- En este momento hay dos árboles VDOM en memoria, el original y el que tiene cambios.
- ReactDOM identifica cuáles objetos VDOM han cambiado, con la finalidad de actualizarlos en el DOM real
- Finalmente actualiza el DOM Virtual.
Con esto, el rendimiento mejora bastante, ya que solo hace los cambios necesarios una SOLA vez en el DOM real; y más que ser una tecnología específica, el VDOM es considerado un patrón.
Importante: No debemos confundir el Shadow DOM con Virtual DOM.
- El Shadow DOM es una tecnología de los navegadores diseñada principalmente para limitar el alcance de variables y CSS en componentes web.
- El Virtual DOM es un concepto que implementan bibliotecas en JavaScript por encima de las APIs de los navegadores.
Además del VDOM, React también usa objetos internos llamados fibers, que sirven para mantener información adicional acerca del árbol de componentes, permitiendo el renderizado incremental VDOM.
v. JavaScript XML (JSX)
Con React, un componente se escribe como una función de JavaScript simple, veamos qué quiere decir esto…
React admite una sintaxis especial llamada JSX (JavaScript XML), se parece mucho a HTML, pero un compilador lo convierte a código JavaScript, veamos el siguiente ejemplo:
El código de arriba NO es HTML y tampoco es un string, es JSX.
React ha decidido usar JSX, ya que al momento de desarrollar es muy familiar a un lenguaje de plantillas, pero, con todas las bondades que tiene JavaScript.
Por detrás JSX se pasa a Babel, donde esté, convertirá el código a JavaScript, para que el navegador pueda entenderlo. Entonces, realmente React NO REQUIERE usar JSX, pero se recomienda, ya que visualmente es más amigable y además React, tiene un control de errores/advertencias bastante útiles.
a — Nuestro primer código en React
Veamos la forma más básica de crear un elemento en React:
Donde:
- ReactDOM — Es la biblioteca que usa React para crear VDOM, con la ayuda del método render.
- <h1>Hello, world</h1> — Es nuestro código JSX (recuerden que es parecido al HTML, pero NO es HTML)
- document.getElementById(‘root’) — Es el nodo HTML, donde va a insertar nuestro elemento.
Es importante saber que TODOS los elementos de React son inmutables (Ver mutabilidad e inmutabilidad[ref]), esto quiere decir que una vez creado no podemos cambiar sus hijos o atributos.
Importante: NO estamos creando componentes, estamos creando elementos, es muy común como desarrolladores al principio confundir ambos conceptos,la forma de diferenciarlos es sabiendo que los elementos constituyen a los componentes, esto quiere decir que uno o más elementos van a conformar un componente.
Para probar el código, primero necesitamos nuestro HTML (index.html):
Podemos observar que estamos importando:
- Babel — Para convertir nuestro código a JavaScript.
- React — Creo que no es necesario explicar el por qué.
- ReactDOM — Para crear nuestros VDOM.
- Y por último nuestro archivo (script.js), donde vamos a poner nuestra lógica.
El siguiente paso es crear nuestro archivo script.js, y agregar el siguiente código:
Veamos nuestro ejemplo:
Sencillo, ¿no?…
b — Variables y Expresiones
Tenemos la ventaja de que al estar trabajando con JavaScript, podemos asignar a nuestro elemento en una variable, veamos el ejemplo:
Es recomendable como buena práctica envolver en paréntesis nuestro elemento, con la finalidad de evitar errores por la inserción automática del punto y coma[ref], también al ponerlo entre paréntesis, nos da la ventaja de acomodar mejor nuestro código, veamos el siguiente ejemplo:
Se ve más amigable nuestro código, ¿no?
Lo interesante de usar JSX es que podemos usar las expresiones[ref] de JavaScript, veamos un ejemplo:
En el código anterior podemos observar que hemos declarado dos variables (name y description), las usamos dentro del JSX envolviendolas mediante llaves ({variable}).
Veamos el ejemplo completo:
Al ser JavaScript, podemos agregar cualquier tipo de expresión (operaciones, variables, funciones, etc).
Otra ventaja es que JSX también es una expresión, por lo que podemos combinarlo dentro de nuestro código JavaScript, veamos el siguiente ejemplo:
Esto es posible, ya que al compilarse el JSX se convierte en llamadas a funciones de JavaScript.
c — Atributos con JSX
También es posible agregar atributos a nuestras etiquetas JSX, como si fuera HTML.
- Todos los atributos de tipo string deben ir entre comillas dobles (id=”anyId”)
- Todos los atributos que vayan dentro de una expresión JavaScript NO deben llevar comillas dobles (src={image})
- Recordemos que JSX es muy parecido a JavaScript, por lo que ReactDOM usa la convención de nomenclatura camelCase en vez de atributos HTML (tabindex debe ser tabIndex, class debe ser className). Las pocas excepciones son los atributos aria-* y data-* , que son minúsculas.
d — Actualizando un elemento
Hasta este momento hemos visto como renderizar un elemento (mediante el método ReactDOM.render()), pero si nosotros queremos actualizar alguna variable, ¿Cómo le haríamos?…
Imaginemos que tenemos un elemento, donde debemos de mostrar los segundos que lleva el usuario en nuestra aplicación (en tiempo real), algo así:
La única forma que conocemos (por ahora), es mediante ReactDOM.render(), así que veamos el código:
Lo que hacemos es rehacer nuestro elemento cada segundo (setInterval[ref]), veamos el ejemplo:
Cuando inspeccionamos el código en consola, podemos observar lo siguiente:
Cuando ReactDOM detecta un cambio, compara el elemento que tiene actualmente en memoria, con el nuevo, y solo aplica las actualizaciones necesarias al DOM real; aunque creamos un elemento nuevo cada segundo.
Importante: En la mayoría de las aplicaciones de React, el ReactDOM.render() solo se manda a llamar una vez, por lo que no es recomendable usarlo para actualizar un elemento; más adelante veremos la forma correcta de hacerlo.
vi. Componentes en React
Los componentes en React aceptan de entrada propiedades (props) y devuelven un elemento que va a aparecer en pantalla.
a — Componentes Funcionales y de Clase
En React, existen dos formas de crear un componente:
- Funcionales — Cuando definimos una función, donde solo acepta un argumento (props) y retorna un elemento JXS.
- De clase [ref]— Cuando creamos una clase con ES6
Ambas formas son válidas para crear un componente en React.
Nota: Es muy importante que el nombre del componente inicie en mayúscula, de lo contrario React puede generar error, ya que va a interpretarlo como una etiqueta de HTML
Nota2: Las propiedades (props) son solo LECTURA, por lo que se recomienda que NUNCA se modifiquen, ya que React tiene solo una regla: Los componentes deben actuar como funciones puras respecto a sus propiedades.
c — Nuestro primer componente
Vamos a crear un componente de tipo funcional:
- Creamos un componente llamado Welcome, que va a aceptar el argumento props y nos va a retornar un elemento JSX tipo h1 con el texto Hello, World!!
- Ahora vamos a llamar a nuestro componente Welcome, y vamos a renderizarlo en el HTML
Podemos observar que así como antes creabamos en la constante element un elemento JSX, podemos de la misma manera, mandar a llamar nuestro elemento Welcome; veamos el ejemplo:
Nota: El index.html sigue siendo el mismo que el de los primeros ejemplos.
Genial, hemos hecho nuestro primer componente en React!!!
Vamos a subir de nivel nuestro ejemplo…
- Dentro de el argumento props, va a recibir una propiedad llamada name, que vamos a sustituir por World
- A nuestro elemento vamos a agregarle un atributo llamado name, donde le mandaremos el texto “Mauricio”
Los atributos que le mandamos a nuestro elemento, son los que va a recibir la propiedad props.
Entonces:
- Estamos creando un componente llamado Welcome
- Creamos una constante element, con el elemento Welcome, donde le agregamos la propiedad name, con el valor Mauricio
- Al ReactDOM.render, le mandamos el elemento (element), este lo va a insertar en el DOM con id root
Veamos el ejemplo:
Ahora vamos a tomar el último ejemplo y vamos a convertirlo en un componente de clase:
Entonces:
- Cuando creamos un componente de clase, debemos extender de React.Component
- El único método obligatorio es render()
d — Composición de componentes
Los componentes pueden llamar a otros componentes, permitiéndonos la abstracción del componente para cualquier nivel de detalle.
La abstracción consiste en aislar un elemento del resto de los elementos que lo acompañan. En programación, el término se refiere al énfasis en el “¿que hace?” más que en el “¿cómo lo hace?” (característica de caja negra)[ref]
Imaginemos que tenemos los siguientes componentes:
Veamos el componente Chat a detalle:
A los componentes Input y Button, realmente no se tienen que enterar que están dentro de un componente Chat o dentro de otros componentes, veamos el ejemplo:
Incluso podemos cambiar a cada uno de ellos sus propiedades, siendo siempre un mismo componente (reutilizable), pero para diferentes propósitos (Chat, Search, Form, etc…).
— Veamos un ejemplo:
La idea es generar un componente, y de ahí ir abstrayendo a componentes; imaginemos que tenemos:
Nota: Para este ejemplo aún no veremos estilos (más adelante retomaremos este ejemplo), por ahora solo nos enfocaremos a crear componentes
Entonces:
- Debemos de crear un componente llamado Card, donde le vamos a pasar image, name, description
Veamos nuestro ejemplo completo:
Al crear así el componente, tenemos varias desventajas:
- Puede ser un poco complicado leer el código y darle mantenimiento
- Reutilizar partes, no es posible
Entonces, vamos a extraer algunos componentes:
- Avatar — El componente que va a mostrar cualquier imagen, va a recibir dos propiedades (image, alt)
- UserInfo — El componente que va a mostrar un título y una descripción, va a recibir dos parámetros (title, description)
Ahora en el componente Card, hacemos los cambios (mandamos a llamar nuestros componentes nuevos)
Veamos el ejemplo completo:
Extraer componentes, al principio puede parecer bastante pesado, pero, tenemos muchas ventajas:
- Tener un ÚNICO catálogo de componentes.
- Menos código, ya que son reutilizables.
- Más fácil de mantener.
- Adaptarlos a otros componentes es más rápido y sencillo.
- Un mejor control cuando nuestra aplicación (aunque sea demasiada grande).
- Para migrarlos a otras aplicaciones, puede ser muy sencillo.
vii. Nuestra primer App
Es bastante común que en nuestra aplicación tengamos que mostrar más de un componente, y como buena práctica, se recomienda crear un componente llamado App, y dentro de él embeber todos los componentes que vamos a necesitar en la primera carga.
Aprovechemos nuestro último ejemplo; crearemos un componente llamado App, donde vamos a llamar varias veces el componente Card:
En el método render, mandamos a llamar a <App />.
Si hemos hecho bien los cambios, nuestra aplicación web debe verse así:
Veamos el ejemplo completo:
Nota: He creado dos constantes kierna y margot, donde cada una va a tener un objeto con propiedades (name, image, description); y se utilizan al momento de crear los componentes de Card.
Nota2: La forma de mandar los datos a la Card, es posible que no sea la mejor forma, solo se ha hecho así para mostrar el ejemplo.
Hasta aquí ya comprendemos los conceptos de UI, UX, así como DOM, VDOM y JSX, de ya sabemos cómo crear elementos, componentes (funcionales y por clase) y una aplicación básica…
En la siguiente entrega vamos a ver React — Ciclo de vida de un componente, propiedades y estado
La entrega pasada vimos Node.js, NPM, Yarn, NVM, Webpack, Babel…
Bibliografía y links que te puede interesar…