Saltearse al contenido

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:

  1. 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.
  2. 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:

  1. Nos permite crear aplicaciones mediante diferentes librerías y frameworks de manera muy sencilla. Por ejemplo, Vue, Preact, LitElement y, por supuesto, React.
  2. Nos proporciona un servidor de desarrollo con recarga en caliente, que nos permite ver los cambios en la aplicación en tiempo real.
  3. 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.).
  4. 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

  1. 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
    1
    mkdir hello-world
    2
    cd hello-world
    3
    code .
  2. Luego, abriremos la terminal de Visual Studio Code (utilizando la combinación de teclas Ctrl + Ñ o Ctrl + J) y ejecutaremos el siguiente comando para crear una aplicación React con Vite:

    Terminal window
    1
    npm create vite@latest

    Este 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.

    Instalación de Vite

  3. Inmediatamente después de ejecutar el comando, se abrirá una interfaz de línea de comandos.

    Configuración de Vite

    Nótese que se agrega un punto (.) al final del comando, el cual hace referencia a la carpeta actual.

  4. Luego, debemos seleccionar la plantilla de la aplicación que deseamos crear. Por supuesto, seleccionaremos la plantilla de React.

    Configuración de Vite

  5. Debemos seleccionar el lenguaje de programación que deseamos utilizar.

    Configuración de Vite

    Veremos que tenemos dos configuraciones disponibles, JavaScript y JavaScript + 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
  6. 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
    1
    npm install

    Este 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 de package.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:

Terminal window
1
npm 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:

index.html
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.

1
const 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:

/src/App.jsx
1
import { useState } from "react";
2 collapsed lines
2
import reactLogo from "./assets/react.svg";
3
import viteLogo from "/vite.svg";
4
import "./App.css";
5
6
function 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
<img
17
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 HMR
30
</p>
31
</div>
32
<p className="read-the-docs">
33
Click on the Vite and React logos to learn more
34
</p>
35
</>
36
);
37
<div>
38
<h1>Hello, world!</h1>
39
</div>
40
}
41
42
export 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:

/src/main.jsx
1
import React from 'react'
2
import ReactDOM from 'react-dom/client'
3
import App from './App.jsx'
4
import './index.css'
5
6
ReactDOM.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:

1
import React from 'react'
2
import ReactDOM from 'react-dom/client'
3
import App from './App.jsx'
4
5
ReactDOM.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.

1
let user = {
2
firstName: 'Carlos',
3
lastName: 'Santana',
4
age: 25,
5
};
6
7
let 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.

1
let 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.

1
function formatName(user) {
2
return user.firstName + ' ' + user.lastName;
3
}
4
5
let user = {
6
firstName: 'Carlos',
7
lastName: 'Santana',
8
age: 25,
9
};
10
11
let 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.

1
function getGreeting(user) {
2
if (user) {
3
return <h1>Hello, {formatName(user)}!</h1>;
4
}
5
return <h1>Hello, Stranger.</h1>;
6
}
1
let users = ['Carlos', 'James', 'Ariana'];
2
3
function 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 &lt; o > en &gt;, de manera que cuando el navegador lea esos datos, los interprete como texto plano en lugar de etiquetas o elementos HTML.

Bibliografía