React 19
(github.com/facebook)19.0.0 (5 de diciembre de 2024)
Nuevas funciones
React
- Actions:
startTransitionahora puede aceptar funciones asíncronas. Estas funciones se llaman "Actions" y actualizan el estado en segundo plano y hacen commit de la UI de una sola vez. Las Actions pueden realizar efectos secundarios como solicitudes asíncronas y esperan a que el trabajo termine antes de que la Transition se complete. useActionState: nuevo hook que permite ordenar Actions dentro de una Transition y acceder al estado. Acepta un estado inicial y un reducer.useOptimistic: nuevo hook para actualizar el estado mientras una Transition está en curso. Cuando la Transition termina, el estado se actualiza con el nuevo valor.use: nueva API para leer recursos durante el renderizado. Acepta una Promise o Context; si se proporciona una Promise, se suspende hasta que el valor se resuelva.- Usar
refcomo prop: ahora se puede usar ref como prop sin necesidad deforwardRef. - Precalentamiento de hermanos de Suspense: cuando un componente se suspende, React hace commit inmediatamente del fallback del límite de Suspense más cercano.
Cliente de React DOM
- Prop
actionde<form>: las Form Actions administran automáticamente el formulario y se integran conuseFormStatus. Restablecen automáticamente el formulario al tener éxito. - Soporte para metadatos del documento: ahora se pueden renderizar de forma nativa etiquetas de metadatos del documento desde componentes.
- Soporte para hojas de estilo: inserta hojas de estilo en el
<head>del cliente antes de revelar el contenido de un límite de Suspense. - Soporte para scripts asíncronos: se pueden renderizar scripts asíncronos desde cualquier parte del árbol de componentes.
Servidor de React DOM
- Se agregan las API
prerenderyprerenderToNodeStream: API para generación de sitios estáticos, diseñadas para funcionar en entornos de streaming como streams de Node.js y Web Streams.
Componentes de servidor de React
- Funcionalidades de RSC: se estabilizan las directivas, los componentes de servidor y las funciones de servidor. Las librerías que incluyen componentes de servidor ahora pueden apuntar a React 19 como dependencia peer.
En desuso
- Acceso a
element.ref: se deja en desuso el acceso aelement.refen favor deelement.props.ref. react-test-renderer: en React 19,react-test-rendererregistra una advertencia de deprecación y cambia a renderizado concurrente para uso web.
Cambios principales
React
- Nueva transformación de JSX obligatoria: se requiere la nueva transformación de JSX para mejorar el tamaño del bundle y permitir usar JSX sin importar React.
- Los errores de renderizado ya no se relanzan: si un Error Boundary no captura el error, se reporta a
window.reportError. - Eliminación de
propTypes: el uso depropTypesse ignora silenciosamente. Se recomienda migrar a TypeScript. - Eliminación de
defaultPropsen funciones: se pueden usar parámetros predeterminados de ES6 en su lugar. - Eliminación de string refs: el uso de string refs debe migrarse a callbacks de ref.
React DOM
- Eliminación de
react-dom/test-utils:actse mueve dereact-dom/test-utilsa react. Las demás utilidades se eliminan. - Eliminación de
ReactDOM.renderyReactDOM.hydrate: se reemplazan porReactDOM.createRootyReactDOM.hydrateRootpara renderizado concurrente.
Cambios destacados
React
- Usar
<Context>como proveedor: ahora se puede renderizar<Context>como proveedor en lugar de<Context.Provider>. - Soporte para custom elements: React 19 pasa todas las pruebas de custom elements.
- Cambios en StrictMode:
useMemoyuseCallbackreutilizan el resultado memorizado del primer renderizado.
React DOM
- Diferencias en errores de hydration: cuando ocurre una discrepancia, React 19 registra un único error que incluye las diferencias del contenido no coincidente.
Cambios en TypeScript
- Se prohíbe el retorno implícito: los refs ahora solo aceptan funciones de limpieza. El retorno implícito genera un error.
- Se requiere el argumento inicial de
useRef: el argumento inicial ahora es obligatorio. - Tipado más estricto de
ReactElement: las props de los elementos de React ahora usanunknownpor defecto en lugar deany.
1 comentarios
Opiniones en Hacker News
No entiendo muy bien por qué tanta gente aquí odia tanto a React
Empecé mi carrera con Laravel y JS puro, pero después de probar React, crear apps escalables empezó a sentirse realista y el frontend también se volvió divertido
Aunque cambie de empresa, React es fácil de retomar, y gracias al soporte de TypeScript y a su gran ecosistema, siento que se puede crear y hacer crecer casi cualquier cosa con bastante facilidad
Tampoco entiendo por qué las funciones nuevas asustan a la gente. Todavía se puede construir una SPA o hacerlo a la antigua, parecido a cuando salieron las bases de datos NoSQL, Spring Boot o Kotlin: si no querías usarlos, no los usabas
Tenía entendido que Jetpack Compose y SwiftUI también se inspiraron en React; creo haberlo visto antes en la documentación de Android, pero ahora no lo encuentro
Aunque todavía no tengo décadas de experiencia, así que no sé qué tan divertido habrá sido para equipos grandes de antes crear grandes web apps como Airbnb con jQuery o JS puro. Hoy ya me cuesta imaginar cómo resolver la gestión de estado, la manipulación del DOM y los efectos secundarios con JS puro
Tal vez algún día yo también me queje de algún framework nuevo y diga que React era mejor
Por lo general, el argumento es algo como “el frontend siempre persigue lo nuevo y brillante, y React es una de esas cosas”, pero React existe desde 2013 y desde alrededor de 2015 ya era bastante mainstream
También dicen que los frameworks y las librerías agregan complejidad, pero cuando uno pregunta qué complejidad en concreto, casi nunca recibe respuesta. Si creas una app significativa sin framework, al final terminas inventando tu propio framework con poca mantenibilidad, pocas pruebas y poca documentación
También se quejan mucho de los pasos de compilación y bundling, pero hoy existen frameworks probados como Expo, Next.js y Meteor, así que casi no hay motivo para armar a mano la configuración de webpack o el pipeline de build
La tendencia de meter frameworks web en todas partes produjo durante los últimos 10 años sitios lentos y propensos a romperse, y en muchos casos, aunque estaban sobrediseñados, no mejoraban mucho la experiencia de usuario de 2008
Para algunos desarrolladores frontend, sea cual sea la pregunta, la respuesta es una combinación de React / Node / Vite / Angular / Vue / Nuxt / Next / Bun / Deno / Svelte / SvelteKit, y si se puede, debería correr sobre decenas de swarms de Docker gobernados por Kubernetes. Es como: “¿Quieres poner tu currículum en línea? Entonces pasemos las próximas 3 semanas dibujando el diagrama de flujo de estados de la app”
React recibe especialmente más críticas porque quienes seguían las modas de frameworks ya pasaron a la siguiente cosa brillante, y quienes originalmente odiaban estos frameworks los siguieron odiando, así que ahora parece que ya no queda nadie para defender este desastre. Creo que el resto de los frameworks correrá la misma suerte con el tiempo
Gran parte de su funcionamiento real está oculto, no es intuitivo, es fácil equivocarse y también es fácil escribir UIs de bajo rendimiento
La carga cognitiva es alta porque hay que estar pensando todo el tiempo qué se ejecuta cuántas veces, qué hay que poner en el arreglo de dependencias y qué debe ir en
useCallbackyuseEffectParte de la comunidad incluso recomienda dependencias de React que el proyecto no necesita, lo que solo aumenta el overhead y la complejidad
También es fácil que se mezclen la lógica de negocio y la lógica de UI
Durante un tiempo, las SPA tenían desventajas frente a las MPA, pero con los estándares web modernos y la adopción del renderizado del lado del servidor en los frameworks SPA, esos problemas hoy están casi resueltos
https://www.youtube.com/watch?v=b2F-DItXtZs
Es un gran lanzamiento, pero también me da algo de pena la gente que está entrando ahora al desarrollo frontend.
Explicaciones como “es un nuevo hook que ordena Actions dentro de Transition, da acceso al estado de la action y al estado pending, recibe un reducer capaz de invocar la Action y el estado inicial que se usa en el primer render, y también recibe una cadena opcional para soportar la mejora progresiva del formulario cuando se pasa al prop form action” hacen que la funcionalidad se vea buena, pero son demasiado largas.
Si hoy empezara a desarrollar sitios web, creo que no sabría por dónde empezar.
Aun así, React sigue siendo un framework excelente y este lanzamiento también es una mejora. La crítica no es solo a React, sino más bien al desarrollo frontend en general.
Es mucho mejor usar renderizado del lado del servidor al estilo de antes con algo como HTMX.
Gané dinero durante 4 años haciendo desarrollo frontend con React y creé mi primer sitio web en 2005; ahora estoy migrando un proyecto de un cliente de React a HTMX y siento que es mucho mejor.
Hay menos bugs y menos trampas por usar mal los hooks.
Si necesito renderizado del lado del cliente, usaría Solid o Vue, pero evitaría React. Si no tienes opción, mucha suerte.
La premisa básica de binding unidireccional, DOM virtual, rerenderizado y cálculo de diferencias nunca me convenció de fondo. Implica usar el doble de memoria del navegador y hacer un rerender completo más un cálculo de diferencias en cada interacción.
En ese momento la respuesta era “primero hagámoslo estable y después rápido”, pero ahora está lleno de estructuras tipo hack para hacerlo rápido, y no es ni rápido ni estable.
Creo que un framework honesto de binding bidireccional al menos garantiza velocidad, y la estabilidad viene de la experiencia. React simplemente es confuso. Me da pena por los ingenieros cuya primera entrada al frontend fue React, porque les va a costar mucho más desaprender y volver a aprender que aprender.
Habiendo pasado por VBScript, JS, jQuery, Mootools, Applets, ActionScript, YUI/Ext/Sencha, Backbone, Knockout, Angular 1, Angular 2, React y Vue 1, les diría que prueben Flutter. De verdad se siente fresco.
El problema es Dart. Si Flutter hubiera sido TypeScript, habría estado un poco más cerca del ideal, pero Dart mantiene vivo el espíritu de churn interminable del frontend.
Los estándares web en general también están más estables que nunca. Los desarrolladores jóvenes no necesitan aprender cientos de trucos de layout para que una página se vea bien en varios navegadores, y a veces necesitan menos hacks para ajustarse a un solo navegador.
Entiendo la fatiga con JavaScript, pero creo que este es uno de los mejores momentos para aprender.
Todo se sentía como desarrollo de verdad, bien hecho, y comparado con la situación anterior fue como respirar aire fresco.
Para el 99% de los desarrolladores, no hace falta algo así hasta que la app crece bastante, e incluso puede que nunca haga falta. React tampoco te obliga a usarlo.
Antes me gustaban los frameworks del lado del cliente como React, pero al final me di cuenta de que agregaron complejidad en todos los lugares posibles.
Metieron complejidad en el backend, el frontend, el stack de DevOps, en todas partes, y se seguirán agregando más capas para sincronizar esa complejidad distribuida.
Que la UI se vuelva a renderizar automáticamente cuando cambian los datos o el modelo es la dirección correcta.
Se puede debatir el detalle de cómo hacerlo, pero actualizar la UI manualmente de forma imperativa cada vez que cambian los datos es difícil de sostener a largo plazo en términos de base de código o tamaño del equipo.
Se agregó una complejidad enorme para hacer que el navegador renderizara cajas de una forma para la que originalmente no estaba pensado, y con el pretexto de cambiar el paradigma de programación también se perdió mucha productividad y ecosistema de herramientas.
Había ideas e implementaciones geniales, pero no sé si valían la pena. A veces me pregunto si no fue una especie de mecanismo de estabilidad laboral.
No es un problema exclusivo de ReactJS; todo el ecosistema JavaScript se volvió loco con librerías y herramientas, pero React en particular era tan molesto para empezar que al final apareció create react app para poder hacer una app hello world en un tiempo razonable.
Dejé de esperar entender por qué había que convertir la API de componentes de clase en hooks.
Se puede elegir un framework más simple, y también se puede evitar la orquestación del servidor.
Si no tienes opción, también puedes iniciar tu propio proyecto creyendo que un stack simple te dará una ventaja de eficiencia.
Una de las mejores partes de este lanzamiento es que ahora ref puede usarse como prop. Ya no hace falta
forwardRef.El post del blog es más fácil de leer: https://react.dev/blog/2024/12/05/react-19
updateNamedevuelve un error enconst error = await updateName(newName);.¿No podría simplemente lanzar un
Error, como corresponde en JS/TS?Si hasta ahora, de 45 comentarios, “redux” se menciona 7 veces, acá me gustaría mencionar Jotai en representación de la familia de Recoil. Probablemente también funcione ya en React 19 sin cambios aparte
Cuando la complejidad del frontend crece lo suficiente, otras herramientas de gestión de estado suelen estorbar más de lo necesario
Si llegaste a odiar React, pero en realidad estás cansado de la pared interminable de constantes de action, del cableado de props, de pelearte con providers/context anidados y de escapar hacia pub-sub, vale la pena probar algo como Jotai
https://github.com/pmndrs/zustand
https://github.com/pmndrs/valtio
Jotai se siente con demasiado boilerplate manual, y Valtio tiene demasiada “magia” de proxies, así que aunque personalmente me guste, no estoy seguro de que sea una buena elección para un equipo
Zustand está en un punto medio entre boilerplate y magia, así que lo elegimos para el proyecto grande que estamos haciendo ahora
Cuando empecé a trabajar en apps React hace unos años, todos los paquetes de gestión de estado que vi estaban llenos de esos términos, y sigue igual
Al final, para apartarme de eso y concentrarme en el trabajo, hice mi propia solución [1], y funciona bien en producción. Es una lástima que no haya una opción popular que funcione de manera parecida
[1] https://github.com/facepunch/react-class-model
Lo bueno de los context hooks es que son componibles y, combinados con queries cacheadas, pueden crear un patrón bastante mantenible
Me da curiosidad qué mejora práctica ofrece Jotai acá
De verdad espero no tener que volver a lidiar con redux ni sagas
No me gustan la mayoría de las funciones nuevas introducidas
Actions y los hooks
useActionState/useOptimisticparecen una gran trampa de complejidad. El hookusetiene un nombre demasiado poco informativo y no maneja promises creadas dentro del componenteSeguramente habrá buenas razones, pero pasar una promise como prop y manejarla con el hook
useparece que va a generar más complejidad que las soluciones alternativas actualesServer Components también parecen bastante complejos, y por suerte todavía no me ha tocado trabajar con ellos
La mejora en los mensajes de error de hydration es bienvenida, y los cambios de usarlo como provider y de usar ref como prop son buenas mejoras de calidad
En general, para crear SPAs me gusta React/Preact. Usando una librería de componentes rica en funciones como MUI junto con una solución simple de gestión de estado como Preact Signals, hacer SPAs resulta bastante intuitivo
Pero me preocupa que la complejidad se vaya colando de a poco. Solo leer la explicación de los hooks nuevos en las notas de lanzamiento ya se siente como una carga cognitiva grande
En cambio, React Compiler sí es una herramienta necesaria. Hará que los componentes sean menos complejos, porque los programadores no tendrán que escribir optimizaciones típicas directamente dentro de ellos
Espero con ganas el lanzamiento y la integración con Vite y otros; por lo que escuché, también planean dar soporte a Preact
Estaría bueno que la API
usecambiara a un nombre distinto del prefijo común de los hooksMe parece que alguien que recién empieza con los hooks de React se va a confundir al ver que
usese puede llamar de forma condicional, pero los hooks normales noMe alegra mucho que hayan retrasado el release para resolver el problema de Suspense en paralelo
Todavía no lo probé, pero tengo muchas expectativas; en general es un release excelente
Última hora: soporte completo para custom elements. Es decir, Web Components