//
Busca en todas las páginas de la documentación
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Los bloques de construcción esenciales que todo aprendiz básico de React debería conocer antes de adentrarse en patrones avanzados.
className en lugar de class, htmlFor en lugar de for, y camelCase para atributos de eventos como onClick.{variable} dentro de JSX para mostrar valores dinámicos -- puedes poner cualquier expresión de JavaScript dentro, pero no sentencias como if o for.useState(initialValue) para obtener un par [value, setValue] -- actualizar el estado con el setter dispara un nuevo render.onClick={handleClick} -- pasa la referencia de la función, nunca la llames con paréntesis como onClick={handleClick()}..map(), cada elemento necesita una key única para que React pueda rastrear de forma eficiente las adiciones, eliminaciones y reordenamientos.{condition ? <A /> : <B />} o {condition && <A />}, ya que no puedes usar sentencias if directamente dentro de JSX.value={state} y onChange={e => setState(e.target.value)} juntos -- establecer value por sí solo hace que el input sea de solo lectura.children -- así es como construyes componentes envoltorio y de layout.useEffect(() => { ... }, [deps]) para cosas que ocurren fuera del render, como llamadas a API, temporizadores o suscripciones.[] significa "ejecutar una vez al montar" -- listar variables significa "volver a ejecutar cuando estas cambien" -- omitirlo significa "ejecutar después de cada render".export default o export para hacer que un componente esté disponible, luego import en otro archivo para usarlo -- el alias @/ apunta a la raíz de tu proyecto.<>...</> (Fragment) cuando no necesitas un <div> adicional -- esto mantiene limpio tu HTML renderizado.style={{ color: "red", fontSize: "16px" }} con propiedades en camelCase -- pero en la práctica, usa un framework de CSS como Tailwind en su lugar.useState separado.interface o type y usa archivos .tsx -- el compilador señalará props faltantes, tipos incorrectos y erratas al instante.Un resumen condensado de las 25 mejores prácticas más importantes extraídas de cada página de esta sección.
function Parent() { function Child() {} /* mal - Child se vuelve a montar en cada render */ }.props.items.push(x)) muta silenciosamente los datos del padre y rompe el modelo de renderizado de React; copia en nuevos arrays u objetos antes de modificar y deja que el padre sea dueño del estado.React.ComponentPropsWithoutRef<"button"> para que cada atributo nativo se mantenga sincronizado con la API del DOM; volver a declarar las props manualmente se desincroniza en cuanto cambia la especificación del DOM.interface ofrece mejores mensajes de error y admite la fusión de declaraciones, así que úsala para las formas de las props de los componentes; reserva type para uniones, tipos mapeados y otras transformaciones que las interfaces no pueden expresar.{count && <Badge />} renderiza la cadena literal "0" cuando count es 0 porque 0 es falsy pero aún así renderizable; usa count > 0 && <Badge /> o un ternario para evitar el infame bug del "0".{ status: "success"; data } | { status: "error"; error } para que TypeScript acote dentro de cada rama; esto elimina el ruido del encadenamiento opcional y hace obvias las ramas inalcanzables.<Spinner /> → <DataTable />, o <input> ↔ <textarea>) desmonta el subárbol antiguo y borra su estado; mantén el mismo tipo y alterna las props cuando quieras que el estado persista.onClick={handleClick} adjunta la función; onClick={handleClick()} la llama durante el render y conecta el valor de retorno como el manejador, lo cual casi nunca es lo que quieres - envuelve en una arrow function cuando necesites inyectar argumentos: onClick={() => handleClick(id)}.onChange de React se corresponde con el evento nativo input, no con el change nativo, por lo que se dispara en cada pulsación de tecla en lugar de al perder el foco - usa onBlur si de verdad quieres la semántica de "confirmar al perder el foco".e.target es el elemento en el que se originó el evento (que puede ser un hijo), mientras que e.currentTarget es el elemento al que está adjunto el manejador; lee los atributos que tú controlas desde currentTarget para evitar sorpresas al hacer clic en elementos anidados.{ passive: false } ni eventos a nivel de window/document; para escuchadores de la tecla Escape, monitores de scroll o touchmove que necesiten preventDefault, usa useEffect + addEventListener sobre una ref y devuelve una función de limpieza.value sin un onChange correspondiente hace que el input sea de solo lectura porque React fija el valor del DOM al estado; o bien combina ambos - <input value={name} onChange={e => setName(e.target.value)} /> - o cambia a defaultValue para un input no controlado.checked/defaultChecked, no value/defaultValue; confundirlos hace lo incorrecto en silencio, ya que el value de un checkbox es el token enviado, no el estado de marcado: <input type="checkbox" checked={on} onChange={e => setOn(e.target.checked)} />.useFormStatus() solo devuelve información de estado pendiente precisa cuando se llama desde dentro de un descendiente del <form>; llamarlo en el mismo componente que renderiza el formulario devuelve valores predeterminados obsoletos sin ningún error, así que extrae el botón de envío en su propio componente.e.target.value siempre es una cadena - incluso para <input type="number"> - así que envuélvela con Number(...) o parseInt(...) antes de usarla en cálculos o almacenar estado tipado: onChange={e => setAge(Number(e.target.value))}.React.createElement, por lo que el atributo class de HTML es className, for es htmlFor, y los estilos toman un objeto en camelCase; usar los nombres de HTML compila pero genera advertencias y puede descartar estilos silenciosamente en entornos estrictos.{user} lanza "Objects are not valid as a React child"; renderiza un campo específico como {user.name} o JSON.stringify(user) para salida de depuración, y recuerda que 0 se renderiza como texto pero null/false/undefined no renderizan nada.children como React.ReactNode (que cubre JSX, cadenas, números, arrays, null) y reserva React.JSX.Element para los tipos de retorno que siempre devuelven un único elemento JSX.key de una lista debe ser única entre sus hermanos (no globalmente), y debe ser estable entre renders - usa item.id, no Math.random() ni Date.now(), o React volverá a montar cada fila y destruirá su estado.index como key en listas que se reordenan, filtran o insertan hace que React reutilice los nodos DOM incorrectos, produciendo valores de input obsoletos y foco roto; las keys de índice solo son seguras para listas verdaderamente estáticas.key de un componente es la forma canónica de reiniciar todo su estado interno - <PlayerProfile key={currentPlayerId} /> vuelve a montarse deliberadamente cuando cambia el jugador, lo cual es una característica, no un truco.<>...</> no acepta una prop key; cuando mapees fragments, importa Fragment y usa <Fragment key={...}>...</Fragment> para evitar advertencias de key duplicada o renders sin key.ref.current no vuelve a renderizar el componente - ese es el punto; recurre a useRef cuando la UI no dependa del valor (IDs de temporizador, observers, caché del último valor) y a useState cuando sí dependa.forwardRef está obsoleto; simplemente tipa ref como una prop ordinaria con React.Ref<HTMLInputElement> y desestructúrala junto a las demás - y recuerda que {...props} ahora también esparce ref, así que extráela explícitamente cuando la pases a través.useEffect, así que conecta los observers como ref={node => { if (!node) return; const obs = new ResizeObserver(...); obs.observe(node); return () => obs.disconnect(); }} en lugar del antiguo baile de comprobación de null.Revisado por Chris St. John·Última actualización: 16 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥