React es una de las bibliotecas más populares para construir interfaces de usuario, y entender cómo usar JavaScript de manera eficiente dentro de React es crucial para cualquier desarrollador. A lo largo del desarrollo de aplicaciones React, se utilizan diversos métodos de JavaScript para gestionar el estado, los eventos y manipular los datos. En esta guía, exploraremos algunos de los métodos más utilizados en React, cómo pueden optimizar el rendimiento de tus componentes y facilitar el desarrollo de aplicaciones reactivas y dinámicas.
// .map() - Crea un nuevo array transformando cada elemento del array original
// aplicando una función a cada elemento.
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2); // [2, 4, 6]
// .filter() - Crea un nuevo array con los elementos que cumplan una condición específica
// definida por la función de callback.
const ages = [15, 25, 35, 12, 40];
const adults = ages.filter(age => age >= 18); // [25, 35, 40]
// .find() - Retorna el primer elemento del array que cumpla con la condición especificada
// en la función. Si no encuentra nada, devuelve undefined.
const users = [{id: 1, name: 'Ana'}, {id: 2, name: 'Juan'}];
const user = users.find(user => user.name === 'Juan'); // {id: 2, name: 'Juan'}
// .reduce() - Reduce un array a un único valor, acumulando los resultados de izquierda
// a derecha según la función proporcionada.
const prices = [10, 20, 30];
const total = prices.reduce((sum, price) => sum + price, 0); // 60
// .some() - Verifica si al menos un elemento del array cumple con la condición
// especificada. Devuelve true o false.
const numbers = [1, 2, 3, 4, 5];
const hasEven = numbers.some(num => num % 2 === 0); // true
// .every() - Verifica si todos los elementos del array cumplen con la condición
// especificada. Devuelve true o false.
const ages = [18, 21, 25, 30];
const allAdults = ages.every(age => age >= 18); // true // Object.keys() - Obtiene todas las propiedades (nombres/keys) de un objeto y las devuelve
// en un array
const persona = {nombre: 'María', edad: 25, ciudad: 'Madrid'};
const propiedades = Object.keys(persona);
console.log(propiedades); // ['nombre', 'edad', 'ciudad']
// Object.values() - Obtiene todos los valores de un objeto y los devuelve en un array
const producto = {item: 'Laptop', precio: 1000, marca: 'HP'};
const valores = Object.values(producto);
console.log(valores); // ['Laptop', 1000, 'HP']
// Object.entries() - Convierte un objeto en un array de arrays, donde cada sub-array
// contiene la pareja [propiedad, valor]
const mascota = {tipo: 'Perro', nombre: 'Max', edad: 3};
const pares = Object.entries(mascota);
console.log(pares); // [['tipo', 'Perro'], ['nombre', 'Max'], ['edad', 3]]
// Ejemplo práctico combinando los tres:
const carrito = {
manzanas: 5,
peras: 3,
naranjas: 8
};
// Con keys - obtener solo los nombres de los productos
console.log(Object.keys(carrito)); // ['manzanas', 'peras', 'naranjas']
// Con values - obtener solo las cantidades
console.log(Object.values(carrito)); // [5, 3, 8]
// Con entries - obtener producto y cantidad juntos
Object.entries(carrito).forEach(([producto, cantidad]) => {
console.log(`Tengo ${cantidad} ${producto}`);
});
// Imprime:
// "Tengo 5 manzanas"
// "Tengo 3 peras"
// "Tengo 8 naranjas" // .split() - Divide un string en un array de substrings basado en un separador
const correo = "usuario@gmail.com";
console.log(correo.split('@')); // ['usuario', 'gmail.com']
const fecha = "2024-03-13";
console.log(fecha.split('-')); // ['2024', '03', '13']
// .includes() - Verifica si un string contiene cierto texto, devuelve true o false
const mensaje = "Hola mundo";
console.log(mensaje.includes('mundo')); // true
console.log(mensaje.includes('hola')); // false (es sensible a mayúsculas)
// .trim() - Elimina espacios en blanco al inicio y final de un string
const textoConEspacios = " Hola Mundo ";
console.log(textoConEspacios.trim()); // "Hola Mundo"
// .replace() - Reemplaza la primera ocurrencia de un texto por otro
const saludo = "Hola Juan";
console.log(saludo.replace('Juan', 'María')); // "Hola María"
// Ejemplo práctico combinando métodos:
const nombreCompleto = " García, Juan Pablo ";
const procesarNombre = nombreCompleto
.trim() // Elimina espacios -> "García, Juan Pablo"
.split(',') // Divide en array -> ['García', ' Juan Pablo']
.map(parte => parte.trim()) // Limpia espacios de cada parte
.reverse() // Invierte el orden
.join(' '); // Une con espacio
console.log(procesarNombre); // "Juan Pablo García"
// Otro ejemplo práctico:
const buscarEnTexto = (texto, busqueda) => {
return texto
.toLowerCase() // Convierte a minúsculas
.includes(busqueda.toLowerCase()); // Busca ignorando mayúsculas/minúsculas
}
console.log(buscarEnTexto("Hola Mundo", "mundo")); // true
console.log(buscarEnTexto("Hola Mundo", "HOLA")); // true // JSON.parse() - Convierte un string con formato JSON a un objeto JavaScript
// Útil cuando recibes datos de una API o localStorage
// Concepto simple: Es como "desempaquetar" un texto que contiene datos
// y convertirlo en algo que JavaScript puede usar
// Ejemplo 1: Datos simples
const textoJSON = '{"nombre": "Juan", "edad": 25}';
const persona = JSON.parse(textoJSON);
console.log(persona.nombre); // "Juan"
console.log(persona.edad); // 25
// Ejemplo 2: Array de datos
const listaJSON = '["manzana", "pera", "uva"]';
const frutas = JSON.parse(listaJSON);
console.log(frutas[0]); // "manzana"
// JSON.stringify() - Convierte un objeto JavaScript a un string JSON
// Útil cuando necesitas enviar datos a una API o guardarlos en localStorage
// Concepto simple: Es como "empaquetar" datos de JavaScript
// en un formato de texto que puede ser enviado o guardado
// Ejemplo 1: Objeto simple
const usuario = {
nombre: "María",
edad: 30,
ciudad: "Madrid"
};
const usuarioJSON = JSON.stringify(usuario);
console.log(usuarioJSON);
// '{"nombre":"María","edad":30,"ciudad":"Madrid"}'
// Ejemplo 2: Array de objetos
const productos = [
{ item: "laptop", precio: 1000 },
{ item: "phone", precio: 500 }
];
const productosJSON = JSON.stringify(productos);
console.log(productosJSON);
// '[{"item":"laptop","precio":1000},{"item":"phone","precio":500}]'
// Ejemplos prácticos:
// 1. Guardando datos en localStorage
const guardarPreferencias = (preferencias) => {
const prefJSON = JSON.stringify(preferencias);
localStorage.setItem('userPrefs', prefJSON);
};
const cargarPreferencias = () => {
const prefJSON = localStorage.getItem('userPrefs');
return JSON.parse(prefJSON);
};
// Uso:
guardarPreferencias({ tema: "oscuro", idioma: "es" });
const prefs = cargarPreferencias();
console.log(prefs.tema); // "oscuro"
// 2. Simulando una respuesta de API
const respuestaAPI = JSON.stringify({
usuario: "pedro123",
ultimoAcceso: "2024-03-13",
activo: true
});
// Procesando la respuesta
const datos = JSON.parse(respuestaAPI);
if (datos.activo) {
console.log(`Bienvenido ${datos.usuario}`);
} JSON.parse() → convierte de texto a objeto/arrayJSON.stringify() → convierte de objeto/array a textoJSON deben usar comillas dobles para las propiedadesstringify funciones o valores undefined// Spread (...) con arrays - Permite expandir un array, copiando todos sus elementos
// en otro array o como argumentos de función
const numeros = [1, 2];
const masNumeros = [...numeros, 3, 4]; // [1, 2, 3, 4]
const frutas = ['manzana', 'pera'];
const masFrutas = ['naranja', ...frutas, 'plátano']; // ['naranja', 'manzana', 'pera', 'plátano']
// Spread con objetos - Copia todas las propiedades de un objeto en otro objeto nuevo,
// permitiendo agregar o sobrescribir propiedades
const usuario = { nombre: 'Ana', edad: 25 };
const usuarioActualizado = { ...usuario, edad: 26, ciudad: 'Madrid' };
// { nombre: 'Ana', edad: 26, ciudad: 'Madrid' }
const producto = { item: 'laptop', precio: 1000 };
const detallesExtra = { ...producto, marca: 'HP', color: 'negro' };
// { item: 'laptop', precio: 1000, marca: 'HP', color: 'negro' }
// Desestructuración - Permite extraer valores de arrays u objetos y asignarlos
// a variables individuales
const persona = { nombre: 'Carlos', edad: 30, ciudad: 'Barcelona' };
const { nombre, ciudad } = persona;
console.log(nombre); // 'Carlos'
console.log(ciudad); // 'Barcelona'
const colores = ['rojo', 'azul', 'verde', 'amarillo'];
const [primero, segundo, ...resto] = colores;
console.log(primero); // 'rojo'
console.log(segundo); // 'azul'
console.log(resto); // ['verde', 'amarillo']
// Ejemplos prácticos adicionales:
// 1. Combinando spread y desestructuración en una función
function crearUsuario({ nombre, edad, ...restoProps }) {
console.log(nombre); // datos específicos
console.log(edad); // datos específicos
console.log(restoProps); // resto de propiedades
}
crearUsuario({
nombre: 'Luis',
edad: 28,
ciudad: 'Valencia',
profesion: 'Developer'
});
// 2. Uniendo arrays y objetos con spread
const equipo1 = ['Juan', 'Ana'];
const equipo2 = ['Carlos', 'María'];
const todosLosEquipos = [...equipo1, ...equipo2];
// ['Juan', 'Ana', 'Carlos', 'María']
const datosPersonales = { nombre: 'Pedro', edad: 30 };
const datosProfesionales = { empresa: 'Tech Inc', puesto: 'Developer' };
const perfilCompleto = { ...datosPersonales, ...datosProfesionales };
// {
// nombre: 'Pedro',
// edad: 30,
// empresa: 'Tech Inc',
// puesto: 'Developer'
// } Local Storage y Session StoragelocalStorage.getItem() y localStorage.setItem(): Guarda y recupera datos en el almacenamiento local del navegador.sessionStorage: Similar a localStorage, pero los datos se borran al cerrar la pestaña.// localStorage - Almacena datos en el navegador de forma permanente
// (persiste incluso después de cerrar el navegador)
// Concepto simple: Es como una pequeña base de datos en tu navegador
// que guarda información incluso después de cerrar la página
// 1. Guardar datos (setItem)
localStorage.setItem('nombre', 'Juan');
localStorage.setItem('edad', '25');
// 2. Obtener datos (getItem)
const nombre = localStorage.getItem('nombre'); // 'Juan'
const edad = localStorage.getItem('edad'); // '25'
// 3. Ejemplo con objetos
const usuario = {
nombre: 'María',
edad: 30
};
// Guardar objeto (debe convertirse a string)
localStorage.setItem('usuario', JSON.stringify(usuario));
// Obtener objeto (convertir de vuelta a objeto)
const usuarioGuardado = JSON.parse(localStorage.getItem('usuario'));
// sessionStorage - Similar a localStorage pero los datos se pierden
// al cerrar la pestaña o el navegador
// Concepto simple: Es como localStorage pero temporal,
// solo dura mientras la página está abierta
// 1. Guardar datos temporales
sessionStorage.setItem('carrito', '["laptop", "mouse"]');
sessionStorage.setItem('totalItems', '2');
// 2. Obtener datos temporales
const carrito = sessionStorage.getItem('carrito');
const total = sessionStorage.getItem('totalItems');
// Ejemplos prácticos:
// 1. Guardar preferencias de usuario
localStorage.setItem('tema', 'oscuro');
localStorage.setItem('idioma', 'es');
// Usar preferencias
const tema = localStorage.getItem('tema');
if (tema === 'oscuro') {
// Aplicar tema oscuro
}
// 2. Carrito de compras temporal
// Se guarda mientras navegas
sessionStorage.setItem('carrito', JSON.stringify([
{ producto: 'laptop', precio: 1000 },
{ producto: 'mouse', precio: 20 }
]));
// Recuperar carrito
const carritoTemp = JSON.parse(sessionStorage.getItem('carrito'));
// 3. Recordar usuario logueado
localStorage.setItem('usuarioLogueado', 'true');
localStorage.setItem('nombreUsuario', 'juan123');
// Verificar si está logueado
if (localStorage.getItem('usuarioLogueado') === 'true') {
console.log('Bienvenido de nuevo');
} localStorage: permanente hasta que se borre manualmentesessionStorage: temporal, se borra al cerrar pestaña/navegadorAmbos almacenan strings (usar JSON.stringify/parse para objetos)
Límite aproximado de 5-10 MB según el navegador Solo almacenan texto, no archivos ni datos binarios.
preventDefault(): Evita el comportamiento predeterminado de un evento (ej. evitar que un formulario se envíe).stopPropagation(): Evita que el evento se propague a elementos padres.function handleClick(event) {
event.preventDefault();
// lógica de manejo
} setTimeout() Ejecuta una función después de un periodo específico.setInterval(): Repite una función en intervalos de tiempo.useEffect(() => {
const timer = setTimeout(() => console.log("Hola"), 1000);
return () => clearTimeout(timer);
}, []); Date.now(): Devuelve la marca de tiempo actual en milisegundos.new Date(): Crea un objeto Date, útil para gestionar fechas en componentes.const now = new Date(); // async/await - Permite escribir código asíncrono de forma más legible y secuencial
// tratando las promesas como si fueran síncronas
async function obtenerUsuario(id) {
try {
const response = await fetch(`https://api.ejemplo.com/usuarios/${id}`);
const usuario = await response.json();
return usuario;
} catch (error) {
console.error('Error al obtener usuario:', error);
}
}
// Promise.all - Ejecuta múltiples promesas en paralelo y espera a que todas se completen
// antes de continuar. Si una falla, todas fallan.
async function obtenerDatosCompletos() {
try {
const [usuarios, productos] = await Promise.all([
fetch('https://api.ejemplo.com/usuarios'),
fetch('https://api.ejemplo.com/productos')
]);
return {
usuarios: await usuarios.json(),
productos: await productos.json()
};
} catch (error) {
console.error('Error al obtener datos:', error);
}
}
// Ejemplos prácticos:
// 1. Obtener datos de un usuario y sus pedidos
async function obtenerDatosUsuario(userId) {
try {
// Obtener información del usuario
const datosUsuario = await fetch(`/api/usuarios/${userId}`);
const usuario = await datosUsuario.json();
// Obtener pedidos del usuario
const datosPedidos = await fetch(`/api/pedidos/${userId}`);
const pedidos = await datosPedidos.json();
return {
usuario,
pedidos
};
} catch (error) {
console.error('Error:', error);
return null;
}
}
// Uso:
obtenerDatosUsuario(123).then(datos => {
if (datos) {
console.log('Usuario:', datos.usuario);
console.log('Pedidos:', datos.pedidos);
}
});
// 2. Cargar múltiples recursos en paralelo
async function iniciarAplicacion() {
try {
const [
datosUsuario,
productos,
configuracion
] = await Promise.all([
fetch('/api/usuario-actual').then(r => r.json()),
fetch('/api/productos').then(r => r.json()),
fetch('/api/configuracion').then(r => r.json())
]);
console.log('Todo cargado:', {
usuario: datosUsuario,
productos,
configuracion
});
return true;
} catch (error) {
console.error('Error al iniciar:', error);
return false;
}
}
// 3. Ejemplo con timeout y manejo de errores
async function obtenerDatosConTimeout() {
try {
// Crear una promesa que se rechaza después de 5 segundos
const timeout = new Promise((_, reject) => {
setTimeout(() => reject('Timeout!'), 5000);
});
// Competir entre la petición y el timeout
const respuesta = await Promise.race([
fetch('https://api.ejemplo.com/datos'),
timeout
]);
const datos = await respuesta.json();
return datos;
} catch (error) {
if (error === 'Timeout!') {
console.error('La petición tardó demasiado');
} else {
console.error('Error en la petición:', error);
}
return null;
}
} async/await para peticiones simplesPromise.all para peticiones paralelastry/catchLa clave es entender que:
async/await hace el código más legible y manejablePromise.all es útil para operaciones paralelas independientes// Operador && (AND lógico) - En React, se usa para renderizado condicional.
// Si la condición es true, renderiza el componente; si es false, no renderiza nada
const MiComponente = ({ usuario }) => {
return (
<div>
{usuario && <p>Bienvenido {usuario.nombre}</p>}
{usuario.esPremium && <BotonPremium />}
</div>
);
};
// Operador || (OR lógico) - Proporciona un valor por defecto cuando
// el primer valor es falsy (false, 0, "", null, undefined)
const nombre = usuario.nombre || "Invitado";
const edad = usuario.edad || 18;
const mensaje = textoPersonalizado || "Bienvenido a nuestra app";
// Operador ?? (Nullish coalescing) - Similar a ||, pero SOLO proporciona el valor
// por defecto cuando el primer valor es null o undefined (NO con "", 0 o false)
const cantidad = producto.cantidad ?? 0;
const precio = datos?.precio ?? 10;
const intentos = usuario.intentos ?? 3;
// Ejemplos prácticos:
// 1. Componente con múltiples renderizados condicionales
const PerfilUsuario = ({ usuario }) => {
return (
<div>
{/* Solo muestra el nombre si existe */}
{usuario.nombre && <h2>{usuario.nombre}</h2>}
{/* Muestra diferentes badges según el tipo de usuario */}
{usuario.esPremium && <PremiumBadge />}
{usuario.esAdmin && <AdminBadge />}
{/* Muestra botón de editar solo si es el propio usuario */}
{usuario.puedeEditar && <BotonEditar />}
</div>
);
};
// 2. Manejo de valores por defecto en un objeto de configuración
const configuracionUsuario = {
tema: usuario.preferencias?.tema || 'claro',
idioma: usuario.preferencias?.idioma || 'es',
notificaciones: usuario.preferencias?.notificaciones ?? true,
intentosMaximos: usuario.limites?.intentos ?? 3
};
// 3. Ejemplo combinando operadores
function mostrarDatosUsuario(usuario) {
const nombre = usuario?.nombre || 'Anónimo';
const nivel = usuario?.nivel ?? 1;
const puntos = usuario?.puntos || 0; // Usa || porque 0 es un valor válido
const configuracion = usuario?.configuracion ?? {};
return (
<div>
<h1>Perfil de {nombre}</h1>
{nivel > 5 && <Experto />}
{puntos > 1000 && <Premio />}
{configuracion.mostrarEstadisticas && <Estadisticas />}
</div>
);
}
// 4. Ejemplo con formularios
const FormularioContacto = ({ datosIniciales }) => {
const [formData, setFormData] = useState({
nombre: datosIniciales?.nombre || '',
email: datosIniciales?.email || '',
telefono: datosIniciales?.telefono ?? '', // Permite guardar número 0
mensaje: datosIniciales?.mensaje || 'Escribe tu mensaje aquí'
});
return (
<form>
{/* Campos del formulario */}
{formData.email && <VerificacionEmail />}
{formData.telefono && <VerificacionSMS />}
</form>
);
};
// 5. Manejo de estados de carga y error
const DatosUsuario = ({ usuario }) => {
const [datos, setDatos] = useState(null);
const [error, setError] = useState(null);
return (
<div>
{/* Muestra error si existe */}
{error && <Error mensaje={error} />}
{/* Muestra loader mientras carga */}
{!datos && !error && <Loader />}
{/* Muestra datos cuando estén disponibles */}
{datos && (
<div>
<h2>{datos.nombre ?? 'Usuario'}</h2>
<p>{datos.bio || 'Sin biografía'}</p>
<span>Nivel: {datos.nivel ?? 1}</span>
</div>
)}
</div>
);
}; && es ideal para renderizado condicional en React|| es útil para valores por defecto cuando 0 o "" son considerados inválidos?? es mejor para valores por defecto cuando solo null/undefined son inválidos.