Qué es React
React es una librería de JavaScript para diseñar interfaces de usuario. Fue desarrollada por Facebook y lanzada en 2013. Desde entonces, se ha convertido en una de las librerías más populares.
Comúnmente se le llama framework, debido a que es empleada como base para el desarrollo de aplicaciones web. Lo cual generó una disputa entre los desarrolladores.
Actualmente, la mayor parte de la comunidad de desarrollador web considera a React como una librería.
Esto se debe a que, en la práctica, no puede utilizarse únicamente React para desarrollar una aplicación web. Es necesario emplear otras librerías y herramientas para obtener una aplicación completa, como por ejemplo, React Router para el sistema de rutas, Redux para el manejo del estado, Webpack para el empaquetado de la aplicación, etc. Por lo tanto, React no puede considerarse como un framework por si mismo, sino como una librería.
No obstante, es una librería sumamente poderosa, que nos permite crear aplicaciones web de una forma muy sencilla y eficiente. Para ello, React utiliza un sistema de componentes, que permite dividir la interfaz de usuario en módulos independientes y reutilizables. Cada componente puede tener su propio estado, que puede cambiar a lo largo del tiempo, y su propio ciclo de vida, que permite ejecutar código en diferentes momentos de la vida del componente. Al emplear componentes, la interfaz de usuario se convierte en una colección de componentes independientes, que dependerán única y exclusivamente de los datos que reciban como entrada y de su propio estado interno.
Además, React utiliza un DOM virtual, que permite actualizar únicamente los elementos que han cambiado, en lugar de actualizar la interfaz completa. Más adelante, veremos en detalle este aspecto.
Herramientas de desarrollo
Para desarrollar aplicaciones con React, será necesario instalar Node.js, un entorno de ejecución, que nos permite ejecutar código JavaScript fuera del navegador. Además, necesitaremos contar con un gestor de paquetes para JavaScript, que nos permite instalar y actualizar librerías, para lo cual utilizaremos npm.
Por otro lado, necesitaremos un editor de código. Existen muchos editores de código, todos ellos con sus ventajas e inconvenientes. En esta materia, utilizaremos Visual Studio Code, un editor de código gratuito y de código abierto, desarrollado por Microsoft.
Claramente, necesitaremos un navegador web para probar nuestras aplicaciones. Los ejemplos y ejercicios presentados en el contenido de la materia han sido probados en Firefox, aunque puede utilizarse cualquier otro navegador web si les parece más conveniente. Únicamente es necesario que el navegador soporte las últimas características de JavaScript, CSS y como recomendación, que soporte la extensión React Developer Tools para depurar aplicaciones React.
Vite
Por último, queremos mencionar la manera en la que crearemos una aplicación React, dado que existen múltiples formas. Por nuestro parte recomendamos emplear Vite, el cual es una herramienta de compilación que tiene como objetivo proporcionar una experiencia de desarrollo más rápida y ágil para proyectos web modernos. Este se encuentra conformado por:
- Un servidor de desarrollo que proporciona mejoras en las funcionalidades sobre módules ES nativos, entre las cuales se incluyen:
- Resolución de dependencias de NPM y preempaquetado. Lo cual permite que los módulos de NPM se resuelvan en tiempo real y se preempaqueten en el servidor de desarrollo.
- HMR (Hot Module Replacement), que permite la recarga en caliente de los módulos de la aplicación en tiempo real, proporcionando actualizaciones instantáneas en el navegador sin necesidad de recargar la página.
- TypeScript, que permite la transpilación de TypeScript a JavaScript en tiempo real.
- Un comando de compilación que empaqueta tu código con Rollup, preconfigurado para generar recursos estáticos altamente optimizados para producción. Rollup es un empaquetador de módulos que permite generar paquetes de JavaScript de manera eficiente, eliminando el código muerto y optimizando el código restante.
Teniendo en cuenta estas características, Vite será la herramienta ideal para desarrollar aplicaciones React, razón por la cual la emplearemos en esta materia.
Entre las ventajas de emplear Vite para desarrollar aplicaciones React, podemos mencionar las siguientes:
- Nos permite crear aplicaciones mediante diferentes librerías y frameworks de manera muy sencilla. Por ejemplo, Vue, Preact, LitElement y, por supuesto, React.
- Nos proporciona un servidor de desarrollo con recarga en caliente, que nos permite ver los cambios en la aplicación en tiempo real.
- Permite integrar múltiples herramientas de desarrollo que, como mencionamos anteriormente, complementan a React para obtener una aplicación completa (React Router, Redux, Webpack, etc.).
- Y una de las ventajas más importantes, es que nos proporciona una estructura de proyecto preconfigurada, lo cual nos permite comenzar a desarrollar aplicaciones React de manera inmediata.
Creando una aplicación React con Vite
-
Una vez instalado Node.js, npm y Visual Studio Code, crearemos una carpeta para almacenar nuestra aplicación React y abriremos Visual Studio Code en dicha carpeta. Por ejemplo, podemos crear una carpeta llamada
hello-world
.Terminal window 1mkdir hello-world2cd hello-world3code . -
Luego, abriremos la terminal de Visual Studio Code (utilizando la combinación de teclas
Ctrl + Ñ
oCtrl + J
) y ejecutaremos el siguiente comando para crear una aplicación React con Vite:Terminal window 1npm create vite@latestTerminal window 1npm init vite@latestEste comando instalará ciertos paquetes para poder ejecutar Vite y nos permitirá configurar una aplicación con una estructura de directorios y archivos preconfigurada recomendada por Vite.
-
Inmediatamente después de ejecutar el comando, se abrirá una interfaz de línea de comandos.
Nótese que se agrega un punto (
.
) al final del comando, el cual hace referencia a la carpeta actual. -
Luego, debemos seleccionar la plantilla de la aplicación que deseamos crear. Por supuesto, seleccionaremos la plantilla de
React
. -
Debemos seleccionar el lenguaje de programación que deseamos utilizar.
Veremos que tenemos dos configuraciones disponibles,
JavaScript
yJavaScript + SWC
. Este último se refiere a SWC (Super-fast Web Compiler), un compilador de alto rendimiento utilizado que tiene la finalidad de convertir código JavaScript para que sea compatible con versiones anteriores de ECMAScript. Motivo por el cual, seleccionaremos esta opción.Cómo resultado, se creará una aplicación React con Vite en la carpeta
hello-world
con la siguiente estructura de directorios y archivos.Directorynode_modules/ Dependencias instaladas
- …
Directorypublic/
- vite.svg
Directorysrc/
Directoryassets/
- react.svg
- App.css
- App.jsx
- index.css
- main.jsx
- .eslintrc.cjs
- .gitignore
- index.html
- package-lock.json
- package.json
- README.md
- vite.config.js
-
Posteriormente, dado que el comando
npm create vite@latest
crea un proyecto con Vite, debemos instalar las dependencias que este proyecto requiere. Para ello, ejecutaremos el siguiente comando:Terminal window 1npm installTerminal window 1npm iEste paso es fundamental, ya que crea la carpeta
node_modules
en la que se almacenan las dependencias de la aplicación.Cabe mencionar que, las dependencias instaladas serán las que figuran en el archivo
package.json
.De esta manera, al crear un repositorio de Git, podemos (o incluso debemos) ignorar la carpeta
node_modules
para no incluir las dependencias de la aplicación en el repositorio.Así, bastará únicamente con el código fuente de la aplicación, los archivos estáticos y el archivo
package.json
para tener un proyecto React completamente funcional.
Estructura de un proyecto React con Vite
Como mencionamos previamente, Vite se encarga de generar un entorno preconfigurado con una estructura de directorios y archivos para desarrollar aplicaciones web. Más aun, nos brinda un componente de ejemplo con el cual podemos comenzar a desarrollar nuestra aplicación.
En particular, Vite crea los siguientes directorios y archivos en la carpeta del proyecto:
- Directorio
src
: almacena el código fuente de la aplicación. - Directorio
public
: almacena los archivos estáticos de la aplicación. - Archivo
index.html
: una plantilla HTML que se encuentra en la raíz del proyecto y establece el punto de entrada de la aplicación. - Archivo
vite.config.js
: establece la configuración de Vite para la aplicación. En el futuro, podremos modificar este archivo para personalizar la configuración de Vite. - Archivo
package.json
: almacena la lista de dependencias de la aplicación. - Archivo
package-lock.json
: almacena la lista de dependencias de la aplicación, junto con la versión exacta de cada una de ellas. A diferencia depackage.json
, este archivo se utiliza para garantizar que las dependencias se instalen en la misma versión en diferentes entornos. - Archivo
.eslintrc.js
: almacena la configuración de ESLint, una herramienta de análisis de código estático para identificar patrones problemáticos en el código JavaScript. Para su correcto funcionamiento, es necesario instalar la extensión de ESLint en Visual Studio Code. - Archivo
.gitignore
: almacena la lista de archivos que no deben ser incluidos en el repositorio de Git, basado en los requerimientos más comunes de los proyectos de la comunidad. - Archivo
README.md
: almacena la documentación de la aplicación.
Al contar con este entorno, podemos, rápidamente, crear un repositorio de Git y comenzar a desarrollar nuestra aplicación.
Finalmente, podemos ejecutar localmante la aplicación con el siguiente comando:
1npm run dev
Por defecto, la aplicación se ejecutará en el puerto 5173
. Por lo tanto, podemos acceder a la aplicación en la dirección http://localhost:5173
desde nuestro navegador web.
Funcionamiento de una aplicación React con Vite
Como podemos notar que en el proyecto de ejemplo anterior, Vite crea un archivo index.html
en el directorio raíz del proyecto, el cual establece el punto de entrada de la aplicación. Este archivo se ve de la siguiente manera:
1<!doctype html>2<html lang="en">3 <head>4 <meta charset="UTF-8" />5 <link rel="icon" type="image/svg+xml" href="/vite.svg" />6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />7 <title>Vite + React</title>8 </head>9 <body>10 <div id="root"></div>11 <script type="module" src="/src/main.jsx"></script>12 </body>13</html>
En este archivo, podemos notar que se carga un archivo main.jsx
ubicado en el directorio src
de la aplicación, el cual contiene el código de la aplicación React integrando todos los componentes que conforman la interfaz de usuario. Ante este escenario, pueden plantearse algunas preguntas, ¿qué es JSX?, ¿qué es un componente?, ¿cómo se integran los componentes en la aplicación?, ¿cómo se crea un componente?, ¿cómo se renderiza un componente?, etc.
Para comenzar, planteamos la siguiente declaración: de variable, la cual puede presentarse en un archivo JSX.
1const element = <h1>Hello, world!</h1>;
A primera vista, esta declaración puede parecer incorrecta, o bien, puede confundirse con una cadena (string
), incluso puede parecer una etiqueta HTML. Sin embargo, esta declaración es completamente válida, dado que JSX (JavaScript XML) es una extensión de JavaScript que nos permite escribir código HTML dentro de JavaScript.
Formalmente, se establece que JSX está produciendo un elemento interpretable directamente por React. En particular, JSX produce elementos de React que serán renderizados en el DOM (Document Object Model).
Como vemos, al crear un proyecto con Vite, tendremos una aplicación React funcional que podemos ejecutar localmente. Sin embargo, emplear los componentes que nos brinda Vite como base para desarrollar una aplicación React puede resultar confuso dado que estamos comenzando a aprender React.
Debido a esto, y para comprender mejor la estructura de una aplicación React, removeremos todo el código “innecesario” de la aplicación y comenzaremos a desarrollar nuestra aplicación desde cero.
Para comenzar, eliminaremos los archivos App.css
e index.css
. Luego modificaremos el archivo App.jsx
para que contenga el siguiente código:
1import { useState } from "react";2 collapsed lines
2import reactLogo from "./assets/react.svg";3import viteLogo from "/vite.svg";4import "./App.css";5
6function App() {7 const [count, setCount] = useState(0);8
9 return (10 <>24 collapsed lines
11 <div>12 <a href="https://vitejs.dev" target="_blank">13 <img src={viteLogo} className="logo" alt="Vite logo" />14 </a>15 <a href="https://react.dev" target="_blank">16 <img17 src={reactLogo}18 className="logo react"19 alt="React logo"20 />21 </a>22 </div>23 <h1>Vite + React</h1>24 <div className="card">25 <button onClick={() => setCount((count) => count + 1)}>26 count is {count}27 </button>28 <p>29 Edit <code>src/App.jsx</code> and save to test HMR30 </p>31 </div>32 <p className="read-the-docs">33 Click on the Vite and React logos to learn more34 </p>35 </>36 );37 <div>38 <h1>Hello, world!</h1>39 </div>40}41
42export default App;
De momento, no entraremos en detalle acerca de la sentencia export default App;
dado que veremos en detalle la importación y exportación de módulos en JavaScript en futuras clases. Por el momento, únicamente debemos entender que mediante esta sentencia, podremos emplear el componente App
en otros archivos de la aplicación.
Por otro último modificaremos el archivo main.jsx
para que se vea de la siguiente manera:
1import React from 'react'2import ReactDOM from 'react-dom/client'3import App from './App.jsx'4import './index.css'5
6ReactDOM.createRoot(document.getElementById('root')).render(7 <React.StrictMode>8 <App />9 </React.StrictMode>,10)
En esta última modificación, queremos resaltar que eliminamos la sentencia <React.StrictMode>
que se encontraba en el archivo main.jsx
. Posteriormente, explicaremos qué es React.StrictMode
y su utilidad, pero por el momento, queremos eliminarlo para estudiar los principios básicos de React.
Por qué utilizar JSX
El modelo que plantea React se base en la idea de que, tanto la lógica de la aplicación como modelo de negocio, como la lógica de renderizado de la interfaz del usuario, se encuentran intrínsecamente relacionadas. Es decir, existen momentos en los cuales el renderizado de algún elemento de la interfaz de usuario depende de la lógica de la aplicación, situaciones como manejar un evento, actualizar el estado del elemento en función del tiempo, procesar los datos para mostrarlos en la interfaz de usuario, entre otros.
Convencionalmente, vimos que exite una separación entre estas dos lógicas se segregan:
- La parte estructural, brindada por HTML.
- La parte lógica (dada por JavaScript).
Sin embargo, esta separación tiende a ser “artificial”, dando lugar a situaciones como las que mencionamos anteriormente, en las cuales la lógica de renderizado depende de la lógica de la aplicación.
Por este motivo, React propone una solución diferente, en la cual se separan intereses en lugar de tecnologías. Para esto, React permite la definición de unidades ligeramente acopladas llamadas componentes, los cuales encapsulan ambas tecnologías (HTML y JavaScript) en una sola entidad. Más adelante, veremos cómo se definen estos componentes en profundidad.
Continuado con la explicación sobre la estructura de una aplicación React desarrollada con Vite, podemos notar que el archivo main.jsx
contiene el siguiente código:
1import React from 'react'2import ReactDOM from 'react-dom/client'3import App from './App.jsx'4
5ReactDOM.createRoot(document.getElementById('root')).render(6 <App />,7)
En este código, podemos notar que se importan las librerías react
y react-dom/client
, las cuales son necesarias para desarrollar aplicaciones React. Además, se importa el componente App
desde el archivo App.jsx
.
De igual manera, podríamos importar otros componentes desde otros archivos, como por ejemplo, un componente Header
desde el archivo Header.jsx
y un componente Footer
desde el archivo Footer.jsx
. De esta manera, podemos dividir la aplicación en múltiples componentes, los cuales pueden ser reutilizados en diferentes partes de la aplicación.
Por otro lado, queremos resaltar la sentencia definida a continuación de la importación de los componentes. En ella se define ReactDOM
el cual, a diferencia del DOM con el que estamos acostumbrados a trabajar, es un DOM virtual.
Como sabemos, el DOM es una interfaz de programación de aplicaciones (API) para documentos HTML y XML, y proporciona una representación estructurada del documento, permitiendo modificar su contenido y presentación visual mediante JavaScript. Para esto el DOM se organiza en una estructura de árbol, en la cual cada elemento del documento es un nodo del árbol.
Este archivo es fundamental para el funcionamiento de la aplicación React, dado que es el encargado de renderizar los componentes en el DOM y será el punto de entrada de la aplicación junto con el archivo index.html
. Por lo tanto, es necesario que este archivo se encuentre en el directorio src
de la aplicación.
Todos los demás archivos pueden encontrarse en cualquier directorio de la aplicación y tener cualquier nombre (aunque es recomendable que los archivos que contienen componentes tengan nombres descriptivos).
Sin embargo, la razón por la cual React define un DOM virtual es para mejorar el rendimiento de la aplicación. En particular, el DOM virtual es una representación en memoria del DOM, que permite actualizar únicamente los elementos que han cambiado, en lugar de actualizar la interfaz completa. De esta manera, React puede determinar cuáles son los elementos que han cambiado y actualizar únicamente esos elementos en el DOM.
Sintaxis JSX
Para entender la sintaxis JSX, y todas las características que nos ofrece, veremos un ejemplo.
Comenzaremos por emplear las expresiones de JSX mediante placeholders, los cuales nos permiten insertar expresiones de JavaScript dentro de JSX. Para ello, utilizaremos llaves ({}
) para delimitar cada expresión.
1let user = {2 firstName: 'Carlos',3 lastName: 'Santana',4 age: 25,5};6
7let element = <h1>Hello, {user.firstName} {user.lastName}!</h1>
Podemos notar que, en este ejemplo, utilizamos llaves ({}
) para insertar las expresiones user.firstName
y user.lastName
dentro de JSX. En general, podemos utilizar cualquier expresión de JavaScript dentro de JSX, siempre y cuando dicha expresión devuelva un valor.
Esto permitirá trabajar de una manera más dinámica, dado que no será necesario definir el contenido de los elementos de la interfaz de usuario de manera estática (como lo hacemos con HTML). El contenido de los elementos React que se renderizarán en el DOM dependerá de la lógica de la aplicación.
1let element = (2 <h1>3 Hello, {user.firstName} {user.lastName}!4 </h1>5);
Por otro lado, resaltamos el hecho de que JSX no es una cadena (string
) ni HTML. JSX es una extensión de JavaScript, en la cual es interpretada como una expresión de JavaScript, al igual que las variables, las funciones, las clases, y cualquier otra estructura de JavaScript.
Esto implica que podemos utilizar JSX como valor de retorno de una función, como argumento de una función, como valor de una variable, como valor de una propiedad de un objeto, etc.
1function formatName(user) {2 return user.firstName + ' ' + user.lastName;3}4
5let user = {6 firstName: 'Carlos',7 lastName: 'Santana',8 age: 25,9};10
11let element = (12 <h1>13 Hello, {formatName(user)}!14 </h1>15);
Tamibén podemos utilizar JSX dentro de una sentencia if
, dentro de un bucle for
, dentro de una sentencia switch
, etc.
1function getGreeting(user) {2 if (user) {3 return <h1>Hello, {formatName(user)}!</h1>;4 }5 return <h1>Hello, Stranger.</h1>;6}
1let users = ['Carlos', 'James', 'Ariana'];2
3function getGreeting(users) {4 let greetings = [];5 for (let i = 0; i < users.length; i++) {6 greetings.push(<h1>Hello, {users[i]}!</h1>);7 }8 return greetings;9}
… y así con cualquier estructura de JavaScript.
Prevención de inyección
Un problema común en aplicaciones web es la inyección de código malicioso, que puede ser utilizado para robar información, modificar la apariencia de la página, redirigir a otra página, etc.
Por ejemplo, un usuario podría intentar ataques de inyección, como la inyección de SQL o de scripts (Cross-Site Scripting, XSS), donde un atacante intenta insertar código malicioso en una aplicación web para ejecutarlo en el servidor o en el navegador de otros usuarios.
Para prevenir este tipo de ataques, React “escapa” automáticamente cualquier valor que se introduzca en JSX. Por ejemplo, si un usuario introduce un script en un campo de texto, React lo escapará y lo mostrará como texto plano, en lugar de ejecutarlo.
”Escapar”, en el contexto de desarrollo web, se refiere al proceso de asegurar que los datos de entrada o salida se traten de manera que no puedan interpretarse como código ejecutable o comandos dentro del contexto en el que se insertan.
Entonces, al escapar los datos, se convierten caracteres específicos que podrían ser interpretados de manera especial por el intérprete (como <
, >
, "
, '
, y &
en HTML) en una forma segura que evita su interpretación como código. Por ejemplo, en el contexto de HTML, escapar un texto significa convertir <
en <
o >
en >
, de manera que cuando el navegador lea esos datos, los interprete como texto plano en lugar de etiquetas o elementos HTML.