▶ 1. JSX — Reglas de Oro
className
clave
En JSX usas
className en lugar de class.
Usar class genera un warning en
consola.
{expresión}
clave
Las llaves {} ejecutan cualquier expresión JS:
variables, ternarios, funciones. No puedes usar
if, for ni let directamente
dentro del JSX.
<>...</>
Cada componente retorna UN solo elemento raíz.
Usa Fragment
<></> para agrupar sin
agregar un <div> extra al DOM.
<img />
cerrar
En JSX, todos los tags vacíos deben
auto-cerrarse:
<img />,
<br />, <input />.
camelCase
Eventos y atributos en camelCase:
onClick,
onChange, tabIndex,
htmlFor (en lugar de for).
Ejemplo JSX válido
function Saludo({ nombre }) { const mayus = nombre.toUpperCase(); return ( <> <h1 className="titulo">Hola, {mayus}</h1> <img src="/foto.jpg" alt="foto" /> </> ); }
▶ 2. Componentes
PascalCase
clave
El nombre SIEMPRE empieza con Mayúscula.
<card> es HTML. <Card> es
React.
function
Un componente es una función que recibe props y
retorna JSX. Nada más.
export default
Para usarlo en otro archivo:
export default MiComp.
Importar: import MiComp from './MiComp'.
<Comp />
Se usa como etiqueta HTML. React ejecuta la función y muestra el
JSX que retorna.
Composición
Los componentes pueden incluir otros componentes.
App es el componente raíz que
contiene a todos los demás.
Anatomía de un componente
// MiBoton.jsx function MiBoton({ texto, color }) { return ( <button className={`btn btn-${color}`}> {texto} </button> ); } export default MiBoton; // Uso en App.jsx: <MiBoton texto="Guardar" color="blue" />
▶ 3. Props
prop={valor}
clave
Se pasan como atributos. Strings con
"", todo lo
demás con {}: números, booleanos, arrays, objetos,
funciones.
{ nombre }
clave
Destructuring en el parámetro. Más limpio que
props.nombre. Es la forma estándar en React moderno.
children
Prop especial. Contiene lo que pongas
entre las etiquetas
del componente. Ideal para layouts, modales y tarjetas
contenedoras.
prop = default
function Btn({ color = "blue" }) — si el padre no
pasa esa prop, usa el valor por defecto.
solo lectura
❌ NUNCA modifiques las props. Son inmutables.
Para datos que deben cambiar, usa
useState.
Props + children en acción
function Card({ titulo, children }) { return ( <div className="card"> <h2>{titulo}</h2> <div>{children}</div> </div> ); } // Uso: <Card titulo="Perfil"> <p>Contenido aquí</p> </Card>
▶ 4. useState Hook
import
clave
import { useState } from 'react' — Es un Hook.
Siempre se importa con llaves. Solo dentro de componentes React.
[val, setVal]
clave
Array destructuring: el primer elemento es el
valor actual, el segundo es la función para actualizarlo.
setValor()
Llamar a la función dispara un re-render. React
actualiza la UI con el nuevo valor automáticamente.
prev => prev+1
Cuando el nuevo estado depende del anterior, usa la
forma funcional:
setN(prev => prev + 1). Más seguro y confiable.
❌ mutar
NUNCA hagas
estado.push() ni
estado.prop = x. La
mutación directa no dispara re-render. Siempre
crea un nuevo valor.
Contador — el ejemplo clásico
import { useState } from 'react'; function Contador() { const [cuenta, setCuenta] = useState(0); return ( <div> <p>Valor: {cuenta}</p> <button onClick={() => setCuenta(prev => prev + 1)}> +1 </button> <button onClick={() => setCuenta(0)}> Reset </button> </div> ); }
▶ 5. Renderizado Condicional
condición &&
clave
Si la condición es true, muestra el elemento. Si
es false, no renderiza nada. Perfecto para
mostrar/ocultar.
cond ? A : B
clave
Ternario: elige entre dos elementos distintos
según una condición. Para decidir qué mostrar, no solo si mostrar.
early return
Retorna antes del JSX principal. Ideal para estados de carga o
datos vacíos:
if (!datos) return <p>Cargando...</p>
className cond.className={activo ? "bg-green-500" : "bg-gray-500"} —
Cambiar clases de Tailwind según estado es muy común.
Los 3 patrones en acción
// 1. && — mostrar o no mostrar {estaLogueado && <BienvenidaMsg />} // 2. Ternario — uno u otro {cargando ? <Spinner /> : <ListaArticulos />} // 3. Early return — salida temprana if (!usuario) return <p>Sin sesión</p>; return <Dashboard user={usuario} />;
▶ 6. Listas con .map()
.map()
clave
Transforma un array de datos en un array de
elementos JSX. Es la forma estándar de renderizar
listas en React.
key
obligatorio
Cada elemento del
.map() DEBE tener
una prop key única. React la usa para optimizar
actualizaciones.
item.id
Usa el id del dato como key.
Evita el índice del array
salvo en listas estáticas que no se reordenan nunca.
.filter()
Encadena
.filter() antes de .map() para
mostrar solo los elementos que cumplen una condición.
Renderizar array de objetos
const articulos = [ { id: 1, titulo: "React Hooks", autor: "Ana" }, { id: 2, titulo: "Tailwind CSS", autor: "Luis" }, ]; // En el JSX del componente: <ul> {articulos.map(art => ( <ArticleCard key={art.id} titulo={art.titulo} autor={art.autor} /> ))} </ul>
▶ 7. Manejo de Eventos
onClick
clave
onClick={handleClick} — Pasa la
referencia, sin paréntesis.
onClick={handleClick()} la ejecutaría al renderizar,
no al hacer click.
() => fn(arg)
Si necesitas pasar argumentos, envuelve en arrow function:
onClick={() => handleEliminar(item.id)}.
onChange
Para inputs:
onChange={e => setValor(e.target.value)}.
e.target.value contiene el texto actual del input.
onSubmit
Siempre llama
e.preventDefault() dentro del handler
para evitar que el formulario recargue la página.
Input controlado + formulario
function FormBusqueda() { const [query, setQuery] = useState(""); function handleSubmit(e) { e.preventDefault(); // ← evita recarga de página console.log("Buscando:", query); } return ( <form onSubmit={handleSubmit}> <input value={query} onChange={e => setQuery(e.target.value)} /> <button>Buscar</button> </form> ); }
▶ 8. Reglas de los Hooks
❌ en if/for
Los Hooks NO pueden ir dentro de
if,
for, ni funciones anidadas. Siempre en el nivel
superior del componente.
✅ nivel raíz
React necesita que el orden de llamada sea
siempre el mismo entre renders. Por eso deben ir al inicio, sin
condiciones.
use*
Los Hooks solo funcionan en componentes React o
en custom hooks. Todos los custom hooks empiezan
con
use: useContador,
useAuth.
useState
Estado local del componente. Ya lo vimos — ¡lo más importante!
useEffect
clase 03
Efectos secundarios: fetch de datos, suscripciones, timers.
useContext
clase 04
Estado global sin pasar props manualmente por cada nivel.
❌ Mal vs ✅ Bien
// ❌ MAL — Hook dentro de un if function Componente() { if (condicion) { const [val, setVal] = useState(0); // ERROR } } // ✅ BIEN — Hook al nivel raíz function Componente() { const [val, setVal] = useState(0); // ✅ if (condicion) { /* usa val aquí */ } }