Fundamentos de ReactJS para Principiantes: La Guía Definitiva

¿Qué es React?

  React JS

React es una biblioteca de JavaScript desarrollada por Facebook (ahora Meta) para construir interfaces de usuario interactivas. Sus principales características son:

  • Declarativo: Describes cómo debe ser la UI y React se encarga del DOM.
  • Basado en Componentes: Construyes interfaces usando piezas reutilizables.
  • Aprende una vez, escribe donde sea: React puede renderizar en diferentes plataformas (web, móvil, escritorio).
  • Eficiente: Usa el Virtual DOM para optimizar las actualizaciones.

Estructura de React JS

Estructura básica de un proyecto React:

bash
mi-primera-app/
├── node_modules/
├── public/
│   ├── index.html
│   └── manifest.json
├── src/
│   ├── components/
│   ├── App.js
│   ├── index.js
│   └── styles/
├── package.json
└── README.md

¿Qué es el Virtual DOM?

El Virtual DOM es una representación ligera en memoria del DOM real. React lo usa para optimizar las actualizaciones de la interfaz.

Cómo funciona:

  1. React mantiene dos copias del Virtual DOM

    • Una representa el estado actual de la UI
    • Otra representa el estado nuevo después de un cambio
  2. Proceso de actualización:

bash
Estado Inicial → Cambio de Estado → Nuevo Virtual DOM
↓
Comparación (Diffing)
↓
Cálculo de diferencias mínimas
↓
Actualización del DOM real (solo los cambios necesarios)

¿Qué es JSX?

JSX (JavaScript XML) es una extensión de sintaxis que combina JavaScript con una estructura similar a HTML, usada en React para escribir componentes de forma declarativa. Permite crear interfaces de usuario de forma más legible y expresiva, ya que el código JSX se convierte en llamadas JavaScript cuando se compila.

Sintaxis Básica

jsx
// JSX básico
const elemento = <h1>Hola Mundo</h1>;

// JSX con múltiples elementos
const contenedor = (
<div>
  <h1>Título</h1>
  <p>Párrafo</p>
</div>
);

// JSX con expresiones JavaScript
const nombre = "Usuario";
const saludo = <h1>Hola, {nombre}</h1>;

Diferencias con HTML

En React, JSX y HTML pueden parecer muy similares, pero existen algunas diferencias clave en la sintaxis que hacen que JSX sea más compatible con JavaScript. Aquí tienes una comparación rápida de cómo ciertos elementos difieren en cada uno:

jsx
// Clase CSS
HTML: <div class="container">
JSX:  <div className="container">

// Eventos
HTML: <button onclick="handleClick()">
JSX:  <button onClick={handleClick}>

// Atributos
HTML: <label for="nombre">
JSX:  <label htmlFor="nombre">

// Estilos en línea
HTML: <div style="color: blue;">
JSX:  <div style={{ color: 'blue' }}>
  Notas

  • Usar className en lugar de class
  • Las propiedades usan camelCase (backgroundColor en lugar de background-color)
  • Las expresiones JavaScript van entre llaves {}

¿Qué son los Componentes en React?

Los componentes en React son bloques reutilizables de código que representan partes de una interfaz, como botones, formularios o secciones completas de una página. Cada componente puede tener su propio estado, lógica y estilo, y al combinarlos se puede crear aplicaciones complejas de forma modular y organizada.

Nuestro Primer Componente

Los componentes son funciones que retornan elementos React:

jsx
// src/components/Tarjeta.js
function Tarjeta({ titulo, descripcion }) {
return (
  <div className="tarjeta">
    <h2>{titulo}</h2>
    <p>{descripcion}</p>
  </div>
);
}

export default Tarjeta;

Componentes Funcionales

Los componentes funcionales en React son funciones JavaScript que retornan código JSX para renderizar una parte de la interfaz. A diferencia de los componentes de clase, son más simples y se enfocan en recibir datos (props) y mostrar la UI sin gestionar estados complejos. Sin embargo, con React Hooks (como useState y useEffect), también pueden manejar estados y efectos, lo que los hace ideales para la mayoría de los componentes en proyectos actuales.

jsx
// Componente básico
function Welcome() {
return <h1>Bienvenido</h1>;
}

// Componente con props
function UserGreeting({ name, role }) {
return (
  <div>
    <h2>Hola, {name}</h2>
    <p>Rol: {role}</p>
  </div>
);
}

// Componente con estado
import { useState } from 'react';

function Counter() {
const [count, setCount] = useState(0);

return (
  <div>
    <p>Contador: {count}</p>
    <button onClick={() => setCount(count + 1)}>
      Incrementar
    </button>
  </div>
);
}

¿Qué son las Props en React?

Las props (abreviatura de “properties”) en React son datos que se pasan de un componente padre a un componente hijo. Permiten que los componentes sean reutilizables y dinámicos, ya que el padre controla los valores y el hijo los recibe como parámetros. Así, las props permiten personalizar y comunicar información entre componentes en una aplicación.

Uso Básico de Props

jsx
// Definición del componente
function UserCard({ name, email, avatar }) {
return (
  <div className="user-card">
    <img src={avatar} alt={name} />
    <h3>{name}</h3>
    <p>{email}</p>
  </div>
);
}

// Uso del componente
function App() {
return (
  <UserCard
    name="Juan Pérez"
    email="juan@ejemplo.com"
    avatar="/images/juan.jpg"
  />
);
}

Props por Defecto

Las props por defecto en React son valores iniciales que un componente usa en caso de que no se le pasen ciertas props desde el componente padre. Esto asegura que el componente tenga datos válidos o un comportamiento predefinido, incluso cuando no reciba todas las props necesarias.

jsx
function Saludo({ nombre = "Invitado" }) {
return <h1>¡Hola, {nombre}!</h1>;
}

// Uso del componente
<Saludo nombre="Carlos" />    // Muestra: ¡Hola, Carlos!
<Saludo />                    // Muestra: ¡Hola, Invitado!
  Explicación

  • Aquí, el componente Saludo tiene una prop nombre.
  • Si no se pasa el nombre, usa el valor predeterminado “Invitado”.
  • Así, cuando Saludo se usa sin pasar nombre, el componente aún muestra un saludo.

Props por Defecto

Props por defecto en React permiten asignar valores predeterminados a las propiedades de un componente en caso de que no se pasen al componente desde el componente padre. Esto se puede lograr usando la propiedad estática defaultProps.

jsx
function Tarjeta({ titulo, descripcion }) {
return (
  <div>
    <h2>{titulo}</h2>
    <p>{descripcion}</p>
  </div>
);
}

// Asignando valores por defecto
Tarjeta.defaultProps = {
titulo: "Título por defecto",
descripcion: "Descripción por defecto"
};

function App() {
return <Tarjeta />;
}

En este ejemplo, si no se pasan las props titulo y descripcion al componente Tarjeta, se usarán los valores por defecto definidos en defaultProps.

Pasando Props Entre Componentes

Pasar props en React (y otros frameworks como Vue o Svelte) es el proceso de enviar datos desde un componente “padre” a un componente “hijo”. Las props permiten la comunicación entre componentes y el intercambio de información dentro de la interfaz de usuario (UI).

jsx
// Componente Padre
function Padre() {
  const mensaje = "¡Hola desde el componente Padre!";
  
  return (
      <div>
          <Hijo mensaje={mensaje} />
      </div>
  );
}

// Componente Hijo
function Hijo(props) {
  return <h1>{props.mensaje}</h1>;
}

export default Padre;

Pasando Variables Entre Componentes

Pasar variables entre componentes se refiere a transferir datos de un componente a otro en frameworks como React. Esto se logra a través de props, que permiten que un componente “padre” pase información a un componente “hijo”.

jsx
// Componente Padre
function Padre() {
  const mensaje = "¡Hola desde el componente Padre!";
  return <Hijo mensaje={mensaje} />;
}

// Componente Hijo
function Hijo(props) {
  return <h1>{props.mensaje}</h1>;
}

En este ejemplo, la variable mensaje en el componente Padre se pasa como una prop al componente Hijo, donde se usa para mostrar el mensaje.

jsx
function App() {
const usuario = "Urian Viera";
const edad = 25;

return (
  <PerfilUsuario 
    nombre={usuario}
    edad={edad}
  />
);
}

En este ejemplo, el componente App pasa las variables usuario y edad como props al componente PerfilUsuario. El componente hijo PerfilUsuario recibe estas props (nombre y edad) y las puede usar dentro de su estructura para mostrar los datos del usuario.

Pasando Objetos Como Props

Pasar objetos como props significa enviar un objeto completo como una propiedad de un componente a otro en React. Esto permite transferir múltiples datos relacionados dentro de un solo valor, en lugar de pasar variables individuales.

jsx
// Componente Padre
function App() {
const usuario = {
  nombre: "Urian Viera",
  edad: 25
};

return <PerfilUsuario usuario={usuario} />;
}

// Componente Hijo
function PerfilUsuario(props) {
return (
  <div>
    <h1>{props.usuario.nombre}</h1>
    <p>Edad: {props.usuario.edad}</p>
  </div>
);
}

En este caso, el componente App pasa un objeto usuario como prop al componente PerfilUsuario, el cual accede a sus propiedades (nombre y edad) para mostrarlas.

Otro ejemplo Pasando Objetos Como Props

Este ejemplo muestra cómo pasar un objeto como prop entre componentes en React. El componente App crea un objeto usuario con varias propiedades y lo pasa al componente Perfil como prop. Dentro de Perfil, se accede a las propiedades del objeto para mostrar los datos del usuario.

jsx
function App() {
const usuario = {
  nombre: "Brenda",
  edad: 28,
  email: "brenda@ejemplo.com"
};

return <Perfil usuario={usuario} />;
}

function Perfil({ usuario }) {
return (
  <div>
    <h2>{usuario.nombre}</h2>
    <p>Edad: {usuario.edad}</p>
    <p>Email: {usuario.email}</p>
  </div>
);
}

Pasando Funciones Como Props

Pasar funciones como props es una técnica en React que permite enviar una función desde un componente “padre” a un componente “hijo”. Esto permite que el hijo ejecute la función del padre, lo que facilita la interacción entre componentes.

jsx
// Componente Padre
function App() {
const saludar = () => alert("¡Hola desde el componente Padre!");

return <Boton onClick={saludar} />;
}

// Componente Hijo
function Boton(props) {
return <button onClick={props.onClick}>Haz clic aquí</button>;
}

En este ejemplo, el componente App pasa la función saludar al componente Boton como prop onClick. El componente hijo ejecuta esa función cuando se hace clic en el botón.

Otro ejemplo Pasando Funciones Como Props

En este ejemplo, el componente Padre pasa la función manejarClick al componente Hijo como prop onButtonClick. El componente Hijo ejecuta esta función al hacer clic en el botón, pasando un mensaje como argumento. Cuando el botón es presionado, el mensaje es mostrado en una alerta.

jsx
function Padre() {
const manejarClick = (mensaje) => {
  alert(mensaje);
};

return <Hijo onButtonClick={manejarClick} />;
}

function Hijo({ onButtonClick }) {
return (
  <button onClick={() => onButtonClick("¡Hola desde el hijo!")}>
    Clic aquí
  </button>
);
}

Template Strings

Template Strings en React (y JavaScript en general) son cadenas de texto que permiten interpolar variables o expresiones dentro de ellas. Se definen usando backticks (`) en lugar de comillas simples o dobles, lo que permite incluir directamente variables con ${}.

jsx
function Saludo({ nombre }) {
return <h1>Hola, {`${nombre}`}</h1>;
}

function App() {
return <Saludo nombre="Urian" />;
}

En este ejemplo, Template Strings se usan para insertar dinámicamente el valor de nombre dentro del saludo en el componente Saludo.

Otro ejemplo con Template Strings

jsx
function Tarjeta({ tipo, estado }) {
const clases = `tarjeta ${tipo} ${estado ? 'activa' : 'inactiva'}`;

return (
  <div className={clases}>
    Contenido de la tarjeta
  </div>
);
}

Destructuring en Props

Destructuring en props es una técnica en JavaScript y React que permite extraer las propiedades de un objeto de forma más concisa. En lugar de acceder a las props con props.propiedad, se pueden desestructurar directamente en los parámetros del componente.

jsx
function Componente({ nombre, edad }) {
return (
  <div>
    <h1>{nombre}</h1>
    <p>Edad: {edad}</p>
  </div>
);
}

function App() {
return <Componente nombre="Urian" edad={25} />;
}

En este ejemplo, las propiedades nombre y edad son extraídas directamente del objeto props usando destructuring en los parámetros del componente Componente. Esto hace el código más limpio y fácil de leer.

Otro ejemplo con Destructuring en Props

En este ejemplo, se muestra cómo el destructuring simplifica el acceso a las propiedades dentro de un componente. Sin destructuring, se accede a las props usando props.titulo y props.descripcion. Con destructuring, estas propiedades se extraen directamente como parámetros del componente, haciendo el código más limpio y legible.

jsx
// Sin destructuring
function Tarjeta(props) {
return (
  <div>
    <h2>{props.titulo}</h2>
    <p>{props.descripcion}</p>
  </div>
);
}

// Con destructuring
function Tarjeta({ titulo, descripcion }) {
return (
  <div>
    <h2>{titulo}</h2>
    <p>{descripcion}</p>
  </div>
);
}

¿Qué son las Children Prop?

La children prop en React es una prop especial que permite pasar contenido anidado dentro de un componente. Básicamente, cualquier elemento o texto que coloques entre las etiquetas de apertura y cierre de un componente se convierte en children. Esto es útil para crear componentes que envuelven o muestran otros elementos de manera flexible, como tarjetas, cuadros de diálogo o contenedores.

Uso de Children

jsx
// Componente contenedor
function Card({ title, children }) {
return (
  <div className="card">
    <div className="card-header">
      <h2>{title}</h2>
    </div>
    <div className="card-body">
      {children}
    </div>
  </div>
);
}

// Uso del componente
function App() {
return (
  <Card title="Bienvenido">
    <p>Este es el contenido de la tarjeta.</p>
    <button>Click me</button>
  </Card>
);
}

¿Qué son los PropTypes?

PropTypes es una herramienta en React para verificar el tipo de las props que se pasan a un componente. Ayuda a garantizar que las props reciban los tipos de datos correctos (por ejemplo, cadenas, números, arrays) y facilita la depuración durante el desarrollo. Si una prop tiene un tipo incorrecto, React mostrará una advertencia en la consola.

jsx
import PropTypes from 'prop-types';

function Saludo({ nombre, edad }) {
return <h1>Hola, {nombre}. Tienes {edad} años.</h1>;
}

Saludo.propTypes = {
nombre: PropTypes.string.isRequired,  // Debe ser una cadena y es obligatoria
edad: PropTypes.number,               // Debe ser un número (opcional)
};

// Uso correcto
<Saludo nombre="Carlos" edad={30} />  // No muestra advertencias

// Uso incorrecto
<Saludo nombre={30} edad="treinta" />  // Muestra advertencias en la consola

¿Qué es Fragments?

Fragments en React son una forma de agrupar múltiples elementos sin agregar un nodo extra al DOM. Esto es útil cuando necesitas devolver varios elementos de un componente sin envolverlos en un contenedor adicional (como un <div>), lo que podría afectar el estilo o el rendimiento.

Uso de Fragments

jsx
import { Fragment } from 'react';

// Sintaxis larga
function ListItems() {
return (
  <Fragment>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </Fragment>
);
}

// Sintaxis corta
function Lista() {
return (
  <>
    <h1>Mi lista</h1>
    <ul>
      <li>Elemento 1</li>
      <li>Elemento 2</li>
      <li>Elemento 3</li>
    </ul>
  </>
);
}

Renderizado Condicional en React

El renderizado condicional en React permite mostrar diferentes elementos o componentes dependiendo de una condición. Esto es útil para cambiar la UI en función de valores dinámicos, como el estado de la aplicación.

Métodos comunes para el renderizado condicional:


1. Usando operadores ternarios

El operador ternario (condition ? expr1 : expr2) es una forma compacta de hacer un renderizado condicional.

jsx
function Saludo({ estaLogueado }) {
return (
  <div>
    {estaLogueado ? <h1>Bienvenido de nuevo!</h1> : <h1>Por favor, inicia sesión</h1>}
  </div>
);
}

2. Usando if dentro de la función de renderizado

Puedes usar una sentencia if para decidir qué renderizar.

jsx
function Saludo({ estaLogueado }) {
if (estaLogueado) {
  return <h1>Bienvenido de nuevo!</h1>;
} else {
  return <h1>Por favor, inicia sesión</h1>;
}
}

3. Operador lógico &&

Cuando solo deseas renderizar algo si una condición es verdadera, puedes usar el operador lógico &&.

jsx
function Mensaje({ mensaje }) {
return <div>{mensaje && <h1>{mensaje}</h1>}</div>;
}

En este caso, si mensaje es verdadero, se renderiza el <h1>, si no, no se muestra nada.

Imágenes en Componentes React

En React, puedes incluir imágenes en tus componentes de varias maneras, dependiendo de si las imágenes son locales o externas. Hay varias formas de usar imágenes:

1. Imágenes locales

Si la imagen está en tu proyecto, puedes importarla o usar una ruta relativa.

jsx
import React from 'react';
import miImagen from './assets/imagen.jpg';

function MiComponente() {
return <img src={miImagen} alt="Descripción" />;
}

export default MiComponente;

2. Imágenes externas:

Para usar imágenes desde una URL externa, solo debes poner la URL directamente en el atributo src.

jsx
function MiComponente() {
return <img src="https://example.com/imagen.jpg" alt="Descripción" />;
}

export default MiComponente;

3. Imágenes dentro del public folder:

Si la imagen está dentro de la carpeta public, puedes hacer referencia a ella usando la ruta relativa.

jsx
function MiComponente() {
return <img src="/images/imagen.jpg" alt="Descripción" />;
}

export default MiComponente;

En este caso, la imagen debería estar ubicada en public/images/imagen.jpg

  Mejores Prácticas

  1. Nombrado de Componentes

    • Usar PascalCase para componentes
    • Usar componentes funcionales con Hooks
    • Nombres descriptivos y específicos
  2. Props

    • Usar destructuring
    • Proporcionar valores por defecto
    • Validar con PropTypes o TypeScript
  3. Composición

    • Mantener componentes pequeños y enfocados
    • Extraer lógica común a componentes reutilizables
  4. JSX

    • Un componente por archivo
    • Mantener el JSX simple y legible
    • Usar keys únicas en listas
    • Extraer lógica compleja a funciones auxiliares
  5. Estructura

    • Organizar componentes por características/páginas
    • Mantener una estructura de carpetas coherente
    • Separar componentes presentacionales y contenedores

Recursos Adicionales

  1. Documentación oficial de React
  2. React Bootstrap
  3. React DevTools