Mejores prácticas de React 19
Un resumen condensado de las 25 mejores prácticas más importantes extraídas de todas las páginas de esta sección.
Busca en todas las páginas de la documentación
Un resumen condensado de las 25 mejores prácticas más importantes extraídas de todas las páginas de esta sección.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
@types/react y @types/react-dom deben actualizarse en la misma instalación a la línea v19; las versiones no coincidentes producen errores de tipo confusos (por ejemplo, ref falta en ComponentProps) que parecen errores de React.<Context.Provider value={…}> está deprecado - renderiza <ThemeContext value={theme}>…</ThemeContext> directamente; el formulario .Provider antiguo sigue funcionando pero registra una advertencia y está destinado a su eliminación.await directamente en el cuerpo - Los Componentes de Cliente no pueden ser async, no pueden usar useState/useEffect, y no tienen acceso a window, document, o localStorage.children o props JSX nombrados desde un padre Componente de Servidor.Date, Map, Set, FormData, arrays tipados, Promises sin esperar, y Acciones de Servidor - pero nunca funciones regulares, instancias de clase, o nodos DOM."use server" convierte funciones async individuales en puntos finales RPC, así que evita ponerlo en la parte superior de un archivo de componente esperando que todas las exportaciones se conviertan en acciones - eso rompe las exportaciones del componente en su lugar.return { success: true, data } o return { success: false, error: "Invalid" } - y reserva throw para fallos genuinamente inesperados capturados por error.tsx."use server" se serializan como campos de formulario ocultos encriptados en cada renderizado, así que extrae los cierres pesados a archivos de acción de nivel superior cuando el estado capturado se vuelve grande.useFormStatus() solo refleja el ancestro <form> más cercano, así que llamarlo en el mismo componente que renderiza el formulario siempre devuelve pending: false - mueve el botón que lee el estado a un hijo del formulario.return { ...prevState, error: "Invalid email" } - y recuerda importarlo desde "react", no "react-dom".use() causa un bucle infinito de Suspense; eleva la creación de promesas a un Componente de Servidor padre, un caché estable, o un prop para que la referencia sea estable a través de renderizados.use(promise) requiere un ancestro Suspense para mostrar el estado de carga y un límite de error para capturar rechazos - sin ambos, la aplicación falla silenciosamente o cuelga en promesas pendientes.use() es legal dentro de if, bucles, y retornos tempranos - if (shouldLoad) { const data = use(promise) } - aprovecha esto para lecturas de contexto condicionales y desenvueltas de promesas protegidas en lugar de forzar formas antiguas de useContext/useEffect.addOptimistic silenciosamente no hace nada a menos que se invoque dentro de una acción de formulario, manejador de Acción de Servidor, o un startTransition explícito; envuelve llamadas de manejador de eventos: startTransition(() => addOptimistic(newItem)) para que la actualización optimista realmente se aplique.updateFn pasada a useOptimistic debe ser pura y producir un nuevo valor - mutar estado o referenciar alcance con efectos secundarios rompe la reversión automática en fallo.useOptimistic con useActionState para que los errores aún se rendericen al usuario después de la reversión.ref como un prop ordinario, así que {...props} accidentalmente reenvía ref junto con todo lo demás - desestructúralo explícitamente: ({ ref, ...props }) => <input ref={ref} {...props} />, especialmente cuando el componente es un paso a través.useEffect); devolver cualquier otra cosa (no función, no indefinido) dispara una advertencia dev, así que devuelve una limpieza o no devuelvas nada en absoluto.<link rel="stylesheet" precedence="…"> opta por la deduplicación, ordenamiento y Suspense-hasta-carga de React - sin precedence, la hoja de estilo es no gestionada y puedes tener FOUC u hojas duplicadas.<title> a <head> pero solo la última renderizada gana, así que dispersar títulos a través de componentes produce resultados dependientes del orden; elige un único sitio de <title> (o usa la API de metadatos del framework) y apégate a ello.preload cuando solo quieras los bytes en caché y preinit cuando también quieras que scripts se ejecuten u hojas de estilo se apliquen; preinit ejecuta scripts inmediatamente y falla si dependen de DOM que aún no se ha renderizado.crossOrigin: "anonymous" en precarga de fuentes incluso para solicitudes del mismo origen - preload("/font.woff2", { as: "font", crossOrigin: "anonymous" }) - sin ello el navegador descarga la fuente dos veces y la sugerencia de precarga se desperdicia.compilationMode: "annotation" y la directiva "use memo" para un despliegue gradual, y usa "use no memo" para opt out de funciones específicas.Revisado por Chris St. John·Última actualización: 16 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥