APRENDE REACTJS: DOM, COMPONENTES Y VISTAS DECLARATIVAS
Introducción a ReactJS: Fundamentos para 2025
ReactJS, conocido simplemente como React, es una biblioteca de JavaScript de código abierto diseñada para construir interfaces de usuario dinámicas y eficientes. Desarrollada por Facebook en 2013, React ha evolucionado hasta convertirse en una herramienta esencial para desarrolladores frontend en 2025, gracias a su enfoque basado en componentes, su manejo eficiente del DOM y su paradigma de programación declarativa. Este tutorial está dirigido a programadores con conocimientos básicos de JavaScript que deseen dominar los conceptos fundamentales de React, como el DOM virtual, los componentes reutilizables y las vistas declarativas en React. A través de explicaciones claras y ejemplos prácticos, exploraremos cómo React simplifica el desarrollo de aplicaciones web modernas, especialmente aplicaciones de página única (SPA).
React destaca por su capacidad para crear interfaces interactivas con un enfoque modular. En lugar de manipular el DOM directamente, React utiliza un DOM virtual, una representación ligera del DOM real, que optimiza las actualizaciones y mejora el rendimiento. Además, su arquitectura basada en componentes permite dividir la interfaz en partes reutilizables, facilitando el mantenimiento y la escalabilidad de las aplicaciones. En este tutorial, desglosaremos estos conceptos clave y proporcionaremos ejemplos de código para ilustrar su implementación práctica.
Configuración inicial de un proyecto React
Antes de sumergirnos en los conceptos técnicos, es fundamental configurar un entorno de desarrollo para React. En 2025, herramientas como Vite y Create React App siguen siendo populares para iniciar proyectos. Vite, en particular, ofrece una configuración más rápida y moderna, por lo que lo usaremos en este tutorial. Para comenzar, asegúrate de tener Node.js instalado (versión 18 o superior recomendada).
Ejecuta los siguientes comandos para crear un proyecto React con Vite:
npm create vite@latest mi-proyecto-react -- --template react
cd mi-proyecto-react
npm install
npm run dev
Esto genera una estructura básica de proyecto:
mi-proyecto-react/
├── public/
│ ├── index.html
│ └── favicon.ico
├── src/
│ ├── assets/
│ ├── components/
│ ├── App.jsx
│ ├── main.jsx
│ └── styles.css
├── package.json
└── vite.config.js
El archivo main.jsx es el punto de entrada, donde se renderiza la aplicación React en el DOM. Un ejemplo típico de main.jsx es:
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import "./styles.css";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
El archivo App.jsx contiene el componente principal de la aplicación. Con el entorno configurado, podemos explorar los conceptos fundamentales de React.
El DOM virtual: Optimización del rendimiento
Uno de los pilares de React es el DOM virtual en React, una representación en memoria del DOM real del navegador. En el desarrollo web tradicional, las actualizaciones directas al DOM son costosas en términos de rendimiento, ya que cada cambio (como actualizar un elemento de texto) requiere recalcular el diseño y volver a renderizar partes de la página. React aborda este problema creando una copia ligera del DOM, conocida como DOM virtual, donde realiza todas las manipulaciones antes de aplicar los cambios al DOM real.
Cuando el estado de una aplicación cambia, React compara el DOM virtual actual con una versión previa, identifica las diferencias (proceso conocido como reconciliación) y actualiza solo las partes necesarias del DOM real. Este enfoque minimiza las operaciones costosas y mejora la velocidad de renderizado, especialmente en aplicaciones complejas con múltiples elementos dinámicos.
Por ejemplo, considera un componente que muestra un contador:
import { useState } from "react";
function Contador() {
const [contador, setContador] = useState(0);
return (
<div>
<p>Contador: {contador}</p>
<button onClick={() => setContador(contador + 1)}>
Incrementar
</button>
</div>
);
}
export default Contador;
Cuando el usuario hace clic en el botón, el estado contador cambia, y React actualiza el DOM virtual. Luego, solo el elemento <p> que muestra el valor del contador se actualiza en el DOM real, en lugar de volver a renderizar toda la página. Este proceso es transparente para el desarrollador, quien solo necesita definir cómo debe verse la interfaz en función del estado.
Componentes: La base de la arquitectura de React
En React, todo gira en torno a los componentes, que son bloques de código reutilizables que representan partes de la interfaz de usuario. Un componente puede ser tan simple como un botón o tan complejo como una página completa. La arquitectura basada en componentes permite dividir una aplicación en partes manejables, lo que facilita el desarrollo, la reutilización y el mantenimiento del código.
Existen dos tipos principales de componentes: funcionales y de clase. En 2025, los componentes funcionales son la norma debido a su simplicidad y compatibilidad con hooks, una característica introducida en React 16.8. Un componente funcional es una función de JavaScript que devuelve JSX, una sintaxis similar a HTML que React interpreta para renderizar elementos en el DOM.
A continuación, un ejemplo de un componente funcional simple:
function Saludo(props) {
return <h1>¡Hola, {props.nombre}!</h1>;
}
export default Saludo;
Este componente recibe una propiedad (props.nombre) y renderiza un saludo personalizado. Para usar este componente en otra parte de la aplicación, se importa y se incluye como si fuera una etiqueta HTML:
import Saludo from "./components/Saludo";
function App() {
return (
<div>
<Saludo nombre="Ana" />
<Saludo nombre="Carlos" />
</div>
);
}
export default App;
La salida en el navegador sería:
<h1>¡Hola, Ana!</h1>
<h1>¡Hola, Carlos!</h1>
Los componentes pueden anidarse y combinarse para formar interfaces complejas. Por ejemplo, un componente Encabezado podría incluir el componente Saludo:
function Encabezado() {
return (
<header>
<Saludo nombre="Usuario" />
<nav>Inicio | Acerca</nav>
</header>
);
}
export default Encabezado;
Esta modularidad es una de las razones por las que React es tan poderoso: permite construir aplicaciones como si fueran piezas de un rompecabezas, donde cada componente tiene una responsabilidad específica.
Vistas declarativas: Simplificando la lógica de la UI
El enfoque declarativo de React es otro de sus puntos fuertes. En lugar de escribir código imperativo que describa paso a paso cómo actualizar el DOM (por ejemplo, buscar un elemento y cambiar su texto), React permite definir cómo debe verse la interfaz en función del estado actual. Este enfoque, conocido como programación declarativa en React, hace que el código sea más legible, predecible y fácil de depurar.
En un enfoque imperativo, para actualizar un elemento del DOM, podrías escribir:
document.getElementById("titulo").innerText = "Nuevo título";
Este método es propenso a errores y difícil de mantener en aplicaciones grandes. En cambio, con React, defines el aspecto de la interfaz declarativamente:
function Titulo({ texto }) {
return <h1>{texto}</h1>;
}
export default Titulo;
Si el valor de texto cambia, React se encarga de actualizar el DOM automáticamente. Este enfoque elimina la necesidad de manipular el DOM directamente, ya que React abstrae esas operaciones. La clave está en el estado y las propiedades, que determinan cómo se renderiza la interfaz.
Por ejemplo, considera un componente que muestra un mensaje según el estado de un interruptor:
import { useState } from "react";
function Interruptor() {
const [encendido, setEncendido] = useState(false);
return (
<div>
<p>El interruptor está {encendido ? "encendido" : "apagado"}</p>
<button onClick={() => setEncendido(!encendido)}>Cambiar</button>
</div>
);
}
export default Interruptor;
Cuando el usuario hace clic en el botón, el estado encendido cambia, y React actualiza la interfaz para reflejar el nuevo estado. El desarrollador solo necesita describir cómo debe verse la interfaz en cada estado, y React maneja el resto.
JSX: La sintaxis que une HTML y JavaScript
JSX es una extensión de sintaxis que permite escribir estructuras similares a HTML dentro de archivos JavaScript. Aunque parece HTML, JSX es en realidad JavaScript que React transforma en llamadas a funciones para crear elementos del DOM virtual. Esta característica hace que el código sea más intuitivo, ya que combina la lógica de la interfaz con la lógica de la aplicación.
Por ejemplo, un componente que usa JSX para renderizar una lista dinámica:
function ListaTareas({ tareas }) {
return (
<ul>
{tareas.map((tarea, index) => (
<li key={index}>{tarea}</li>
))}
</ul>
);
}
export default ListaTareas;
Para usar este componente:
function App() {
const tareas = ["Comprar víveres", "Estudiar React", "Hacer ejercicio"];
return (
<div>
<h1>Mis tareas</h1>
<ListaTareas tareas={tareas} />
</div>
);
}
export default App;
La salida sería:
<h1>Mis tareas</h1>
<ul>
<li>Comprar víveres</li>
<li>Estudiar React</li>
<li>Hacer ejercicio</li>
</ul>
JSX permite incrustar expresiones de JavaScript dentro de llaves {} y usar estructuras de control como map para generar contenido dinámico. Además, la prop key en el ejemplo ayuda a React a identificar elementos únicos en listas, optimizando las actualizaciones del DOM.
Estado y propiedades: Dinamismo en los componentes
El estado y las propiedades (props) son fundamentales para crear interfaces dinámicas. Las propiedades en componentes React son datos que un componente recibe de su padre, mientras que el estado es un mecanismo interno que permite a un componente gestionar datos que cambian con el tiempo.
Las props son inmutables y se pasan de un componente padre a un hijo. Por ejemplo:
function Boton({ texto, onClick }) {
return <button onClick={onClick}>{texto}</button>;
}
export default Boton;
El estado, por otro lado, se gestiona con el hook useState en componentes funcionales:
import { useState } from "react";
function Formulario() {
const [nombre, setNombre] = useState("");
return (
<div>
<input
type="text"
value={nombre}
onChange={(e) => setNombre(e.target.value)}
placeholder="Escribe tu nombre"
/>
<p>Hola, {nombre || "invitado"}</p>
</div>
);
}
export default Formulario;
En este ejemplo, el estado nombre se actualiza cada vez que el usuario escribe en el campo de entrada, y la interfaz refleja el cambio automáticamente. La combinación de props y estado permite crear componentes flexibles y reutilizables.
Manejo de eventos en React
React proporciona una forma declarativa de manejar eventos, como clics o entradas de teclado, mediante atributos como onClick o onChange. A diferencia de JavaScript puro, los manejadores de eventos en React son funciones que se pasan como props o se definen dentro del componente.
Por ejemplo, un componente que cuenta clics:
import { useState } from "react";
function ContadorClics() {
const [clics, setClics] = useState(0);
const manejarClic = () => {
setClics(clics + 1);
};
return (
<div>
<p>Número de clics: {clics}</p>
<button onClick={manejarClic}>Haz clic</button>
</div>
);
}
export default ContadorClics;
El atributo onClick recibe una función que se ejecuta cuando el usuario hace clic en el botón. Este enfoque es más limpio que agregar escuchadores de eventos directamente al DOM, ya que React gestiona los eventos de manera eficiente.
Optimización y mejores prácticas en 2025
En 2025, optimizar aplicaciones React es más importante que nunca, especialmente para aplicaciones grandes. Algunas mejores prácticas incluyen:
-
Usar keys en listas: Como se mostró en el ejemplo de
ListaTareas, asignar una propkeyúnica a cada elemento de una lista ayuda a React a identificar cambios de manera eficiente. -
Evitar mutaciones directas del estado: Siempre usa funciones como
setStatepara actualizar el estado, ya que las mutaciones directas no desencadenan re-renderizados. -
Componentes puros: Escribe componentes que dependan solo de sus props y estado para facilitar la depuración y las pruebas.
-
Usar hooks modernos: Hooks como
useMemoyuseCallbackayudan a optimizar el rendimiento al evitar cálculos o renderizados innecesarios.
Por ejemplo, para evitar renderizados innecesarios en una lista grande:
import { useMemo } from "react";
function ListaFiltrada({ elementos }) {
const elementosFiltrados = useMemo(() => {
return elementos.filter((el) => el.length > 3);
}, [elementos]);
return (
<ul>
{elementosFiltrados.map((el, index) => (
<li key={index}>{el}</li>
))}
</ul>
);
}
export default ListaFiltrada;
El hook useMemo asegura que el filtrado solo se realice cuando elementos cambia, mejorando el rendimiento.
Conclusiones
ReactJS sigue siendo una de las bibliotecas más poderosas y versátiles para el desarrollo frontend en 2025. Su enfoque basado en componentes, combinado con el DOM virtual y las vistas declarativas, permite a los desarrolladores crear interfaces de usuario dinámicas, escalables y eficientes con relativa facilidad. A lo largo de este tutorial, hemos explorado cómo configurar un proyecto React, el funcionamiento del DOM virtual, la creación de componentes reutilizables, el uso de JSX, la gestión de estado y propiedades, y el manejo de eventos. También hemos destacado mejores prácticas para optimizar el rendimiento, como el uso de keys y hooks modernos.
Dominar React requiere práctica, pero los conceptos fundamentales presentados aquí proporcionan una base sólida para construir aplicaciones web modernas. Ya sea que estés desarrollando una aplicación de página única o una interfaz compleja, React te equipa con las herramientas necesarias para crear experiencias de usuario fluidas y mantenibles. Continúa experimentando con proyectos prácticos y explora bibliotecas complementarias como React Router o Redux para llevar tus habilidades al siguiente nivel.