React 19
(github.com/facebook)19.0.0 (5. Dezember 2024)
Neue Funktionen
React
- Actions:
startTransitionkann jetzt asynchrone Funktionen annehmen. Diese Funktionen werden als „Actions“ bezeichnet, aktualisieren den Status im Hintergrund und committen die UI in einem Schritt. Actions können Nebenwirkungen wie asynchrone Requests ausführen und warten auf deren Abschluss, bevor die Transition beendet wird. useActionState: Ein neuer Hook, der Actions innerhalb einer Transition sequenziert und Zugriff auf den Status ermöglicht. Er nimmt einen Initialzustand und einen Reducer entgegen.useOptimistic: Ein neuer Hook zum Aktualisieren des Status, während eine Transition läuft. Nach Abschluss der Transition wird der Status auf den neuen Wert aktualisiert.use: Eine neue API zum Lesen von Ressourcen während des Renderns. Sie akzeptiert ein Promise oder Context; wird ein Promise übergeben, wird die Ausführung angehalten, bis der Wert aufgelöst ist.refals Prop verwenden:refkann jetzt als Prop verwendet werden, ohne dassforwardReferforderlich ist.- Suspense-Sibling-Prewarming: Wenn eine Komponente suspendiert wird, committet React sofort den Fallback der nächstgelegenen Suspense-Grenze.
React DOM Client
<form> action-Prop: Form Actions verwalten Formulare automatisch und sind inuseFormStatusintegriert. Bei Erfolg wird das Formular automatisch zurückgesetzt.- Unterstützung für Dokument-Metadaten: Dokument-Metadaten-Tags können nativ aus Komponenten heraus gerendert werden.
- Stylesheet-Unterstützung: Stylesheets werden in das
<head>des Clients eingefügt, bevor Inhalte innerhalb einer Suspense-Grenze sichtbar gemacht werden. - Unterstützung für asynchrone Skripte: Asynchrone Skripte können überall im Komponentenbaum gerendert werden.
React DOM Server
prerender- undprerenderToNodeStream-API hinzugefügt: APIs für die Generierung statischer Websites, entwickelt für Streaming-Umgebungen wie Node.js-Streams und Web Streams.
React Server Components
- RSC-Funktionen: Direktiven, Server Components und Server Functions sind jetzt stabil. Bibliotheken mit Server Components können React 19 nun als Peer Dependency adressieren.
Veraltet
- Zugriff auf
element.ref: Der Zugriff aufelement.refwird zugunsten vonelement.props.refals veraltet markiert. react-test-renderer: In React 19 protokolliertreact-test-renderereine Deprecation-Warnung und wechselt für die Web-Nutzung auf Concurrent Rendering.
Wichtige Änderungen
React
- Neue JSX-Transformation erforderlich: Eine neue JSX-Transformation ist notwendig, um die Bundle-Größe zu verbessern und JSX ohne Import von React zu ermöglichen.
- Rendering-Fehler werden nicht erneut geworfen: Wenn ein Fehler nicht von einer Error Boundary abgefangen wird, wird er an
window.reportErrorgemeldet. propTypesentfernt: Die Verwendung vonpropTypeswird stillschweigend ignoriert. Eine Migration zu TypeScript wird empfohlen.defaultPropsfür Funktionen entfernt: Stattdessen können ES6-Default-Parameter verwendet werden.- String-Refs entfernt: Die Verwendung von String-Refs sollte auf Ref-Callbacks migriert werden.
React DOM
react-dom/test-utilsentfernt:actwurde vonreact-dom/test-utilsnachreactverschoben. Andere Utilities wurden entfernt.ReactDOM.render,ReactDOM.hydrateentfernt: Ersetzt durchReactDOM.createRootundReactDOM.hydrateRootfür Concurrent Rendering.
Erwähnenswerte Änderungen
React
<Context>als Provider verwenden:<Context>kann jetzt als Provider gerendert werden statt<Context.Provider>.- Unterstützung für Custom Elements: React 19 besteht alle Tests für Custom Elements.
- StrictMode-Änderungen:
useMemounduseCallbackverwenden das Memoization-Ergebnis des ersten Renderings erneut.
React DOM
- Diffs bei Hydration-Fehlern: Bei einem Mismatch protokolliert React 19 einen einzelnen Fehler, der die Unterschiede im nicht übereinstimmenden Inhalt enthält.
TypeScript-Änderungen
- Keine impliziten Rückgaben erlaubt: Refs akzeptieren jetzt nur noch Cleanup-Funktionen. Implizite Rückgaben führen zu einem Fehler.
- Initiales Argument für
useReferforderlich: Das Initialargument ist jetzt verpflichtend. - Strikteres
ReactElement-Typing: Props von React-Elementen sind nun standardmäßigunknownstattany.
1 Kommentare
Meinungen auf Hacker News
Ich verstehe nicht so recht, warum hier so viele Leute React hassen.
Ich habe meine Karriere mit Laravel und purem JS begonnen, aber seit ich React ausprobiert habe, fühlt es sich realistisch an, skalierbare Apps zu bauen, und Frontend macht mir auch Spaß.
Selbst wenn man das Unternehmen wechselt, kommt man leicht wieder in React hinein, und dank TypeScript-Unterstützung und großem Ökosystem hat man das Gefühl, so ziemlich alles recht einfach bauen und ausbauen zu können.
Ich verstehe auch nicht, warum neue Funktionen den Leuten Angst machen. Man kann immer noch SPAs oder im alten Stil bauen; ähnlich wie bei NoSQL-DBs, Spring Boot oder Kotlin: Wer es nicht nutzen wollte, musste es nicht nutzen.
Ich dachte auch, Jetpack Compose und SwiftUI seien von React inspiriert; ich meine, das früher in der Android-Dokumentation gesehen zu haben, finde es aber jetzt nicht mehr.
Allerdings habe ich noch keine jahrzehntelange Erfahrung, daher weiß ich nicht, wie angenehm es früher für große Teams war, große Web-Apps wie Airbnb mit jQuery oder purem JS zu bauen. Heute kann ich mir kaum noch vorstellen, wie man State Management, DOM-Manipulation und Side Effects in purem JS lösen würde.
Vielleicht werde ich mich eines Tages auch über ein neues Framework beschweren und sagen, React sei gut gewesen.
Meist lautet die Logik etwa: „Frontend jagt immer dem neuen glänzenden Ding hinterher, und React ist eines davon.“ Dabei gibt es React seit 2013, und ab etwa 2015 war es ziemlich Mainstream.
Außerdem heißt es, Frameworks und Libraries würden Komplexität hinzufügen, aber wenn man nachfragt, welche Komplexität konkret gemeint ist, bekommt man kaum eine Antwort. Wenn man ohne Framework eine nennenswerte App baut, erfindet man am Ende ein eigenes Framework, dem es an Wartbarkeit, Tests und Dokumentation mangelt.
Auch über Kompilierungs- und Bundling-Schritte wird oft geklagt, aber inzwischen gibt es bewährte Frameworks wie Expo, Next.js und Meteor, sodass es kaum noch einen Grund gibt, webpack-Konfiguration oder Build-Pipeline selbst zu schreiben.
Der Trend, überall Web-Frameworks hineinzudrücken, hat in den letzten zehn Jahren langsame, leicht kaputtgehende Websites hervorgebracht, die trotz Overengineering oft keine deutlich bessere User Experience bieten als 2008.
Für manche Frontend-Entwickler lautet die Antwort, egal wie die Frage heißt, irgendeine Kombination aus React / Node / Vite / Angular / Vue / Nuxt / Next / Bun / Deno / Svelte / SvelteKit, und wenn möglich sollte das Ganze auf Dutzenden von Docker-Swarms laufen, die von Kubernetes beherrscht werden. Nach dem Motto: „Du willst deinen Lebenslauf online stellen? Dann zeichnen wir in den nächsten drei Wochen erst mal das Zustandsflussdiagramm der App.“
Dass React besonders viel abbekommt, liegt wohl daran, dass die Leute, die Framework-Hypes hinterherlaufen, schon zum nächsten glänzenden Ding weitergezogen sind, während diejenigen, die solche Frameworks schon immer gehasst haben, sie weiter hassen. Jetzt ist niemand mehr übrig, der dieses Chaos verteidigt. Den übrigen Frameworks dürfte mit der Zeit dasselbe Schicksal drohen.
Viel vom tatsächlichen Verhalten ist verborgen und nicht intuitiv; man macht leicht Fehler und schreibt ebenso leicht UI mit schlechter Performance.
Man muss ständig darüber nachdenken, was wie oft ausgeführt wird, was in das Dependency-Array gehört und was in
useCallbackunduseEffectgehört; das erzeugt eine hohe kognitive Last.Teile der Community empfehlen sogar React-Abhängigkeiten, die ein Projekt gar nicht braucht, und erhöhen damit nur Overhead und Komplexität.
Außerdem vermischen sich Business-Logik und UI-Logik leicht.
Eine Zeit lang hatten SPAs gegenüber MPAs Nachteile, aber durch moderne Webstandards und die Einführung von serverseitigem Rendering in SPA-Frameworks sind diese Probleme heute weitgehend gelöst.
https://www.youtube.com/watch?v=b2F-DItXtZs
Ein großartiges Release, aber ich habe auch ein bisschen Mitleid mit Leuten, die jetzt in die Frontend-Entwicklung einsteigen.
Erklärungen wie „ein neuer Hook, der Actions innerhalb einer Transition ordnet, Zugriff auf den Action-Status und den Pending-Status bietet, einen Reducer entgegen nimmt, der die Action aufrufen kann, sowie den Initialzustand für das erste Rendering, und außerdem einen optionalen String akzeptiert, um progressive Enhancement für Formulare zu unterstützen, wenn er an die form action prop übergeben wird“ klingen zwar nach nützlicher Funktionalität, sind aber extrem ausschweifend.
Wenn man heute mit Website-Entwicklung anfängt, dürfte es schwer sein zu wissen, wo man überhaupt beginnen soll.
Trotzdem ist React weiterhin ein hervorragendes Framework, und auch dieses Release ist eine Verbesserung. Die Kritik richtet sich weniger nur gegen React als gegen die Frontend-Entwicklung insgesamt.
Klassisches Server-seitiges Rendering mit etwas wie HTMX ist deutlich besser.
Ich habe vier Jahre lang mit React-Frontend-Entwicklung Geld verdient und 2005 meine erste Website gebaut; aktuell migriere ich ein Kundenprojekt von React zu HTMX und es fühlt sich deutlich besser an.
Weniger Bugs, weniger Fallstricke durch falsch verwendete Hooks.
Wenn ich clientseitiges Rendering bräuchte, würde ich Solid oder Vue nutzen, aber React meiden. Wenn man keine Wahl hat: viel Glück.
Die Grundannahmen von One-Way Binding, virtuellem DOM, Re-Rendering und Diffing haben mich fundamental nicht überzeugt. Das bedeutet, den Browserspeicher doppelt zu nutzen und bei jeder Interaktion alles neu zu rendern und zu vergleichen.
Damals lautete die Antwort: „Erst stabil machen, dann schnell machen“, aber heute ist es voller hackiger Strukturen, um es schnell zu machen, und es ist weder schnell noch stabil.
Ehrliche Two-Way-Binding-Frameworks garantieren zumindest Geschwindigkeit, und Stabilität kommt meiner Meinung nach aus Erfahrung. React ist einfach chaotisch. Mir tun die Engineers leid, deren erster Einstieg ins Frontend React war; ich glaube, Verlernen und Neu-Lernen ist viel schwieriger als Lernen.
Aus der Perspektive von jemandem, der VBScript, JS, jQuery, Mootools, Applets, ActionScript, YUI/Ext/Sencha, Backbone, Knockout, Angular 1, Angular 2, React und Vue 1 mitgemacht hat, würde ich empfehlen, Flutter auszuprobieren. Es fühlt sich wirklich frisch an.
Allerdings ist Dart das Problem. Wäre Flutter TypeScript, käme es einem Ideal etwas näher, aber Dart hält den endlosen Churn-Geist des Frontends am Leben.
Auch Webstandards sind insgesamt stabiler als je zuvor. Junge Entwickler müssen nicht mehr Hunderte Layout-Tricks lernen, damit Seiten in mehreren Browsern ordentlich aussehen, und brauchen auch seltener Hacks nur für einen bestimmten Browser.
JavaScript-Müdigkeit kann ich verstehen, aber ich halte jetzt für eine der besten Zeiten zum Lernen.
Das Ganze fühlte sich tatsächlich wie richtige Entwicklung an, und im Vergleich zur vorherigen Situation war es wie frische Luft.
99 % der Entwickler brauchen solche Funktionen nicht, bevor ihre App eine gewisse Größe erreicht hat, und vielleicht auch nie. React zwingt einen auch nicht dazu.
Ich mochte clientseitige Frameworks wie React einmal, habe aber schließlich erkannt, dass sie überall, wo es möglich war, Komplexität hinzugefügt haben.
Backend, Frontend, DevOps-Stack – überall kam Komplexität hinein, und um diese verteilte Komplexität zu synchronisieren, werden immer weitere Schichten hinzukommen.
Dass die UI automatisch neu gerendert wird, wenn sich Daten oder Modelle ändern, ist die richtige Richtung.
Über die Details kann man streiten, aber die UI bei jeder Datenänderung imperativ selbst anzupassen, hält bei größeren Codebases oder Teams nicht lange durch.
Es hat enorme Komplexität daraufgesetzt, um Webbrowser dazu zu bringen, Boxen auf eine Weise zu rendern, für die sie ursprünglich nicht gedacht waren, und unter dem Vorwand, das Coding-Paradigma zu ändern, hat man viel Produktivität und Tooling verloren.
Es gab coole Ideen und Implementierungen, aber ich weiß nicht, ob es das wert war. Manchmal frage ich mich, ob es eine Art Jobgarantie war.
Es ist nicht nur ein ReactJS-Problem; das gesamte JavaScript-Ökosystem ist mit Libraries und Tools durchgedreht. Aber React war besonders nervig für den Einstieg, sodass schließlich create react app entstand, damit man in vertretbarer Zeit eine Hello-World-App bauen konnte.
Ich habe aufgehört zu erwarten, den Grund zu verstehen, warum die Klassenkomponenten-API durch Hooks ersetzt wurde.
Man könnte ein einfacheres Framework wählen oder Server-Orchestrierung vermeiden.
Wenn man keine Wahl hat, könnte man auch selbst ein Projekt starten, bei dem man glaubt, mit einem einfachen Stack einen Effizienzvorteil zu haben.
Einer der besten Teile dieses Releases ist, dass man ref als prop verwenden kann.
forwardRefist jetzt nicht mehr nötig.Der Blogpost ist besser lesbar: https://react.dev/blog/2024/12/05/react-19
updateNameinconst error = await updateName(newName);einen Fehler zurückgibt.Kann man nicht JS/TS-typisch einfach ein
Errorwerfen?Wenn unter den bisher 45 Kommentaren „redux“ 7-mal erwähnt wurde, möchte ich hier als Vertreter der Recoil-Familie Jotai nennen. Vermutlich funktioniert es auch mit React 19 bereits ohne separate Änderungen.
Wenn die Frontend-Komplexität groß genug wird, stehen andere State-Management-Tools oft mehr im Weg als nötig.
Wenn man React inzwischen nicht mehr mag, in Wahrheit aber nur von endlosen Wänden aus action-Konstanten, prop-Verkabelung, Kämpfen mit verschachtelten Providern/Contexts und der Flucht in pub-sub erschöpft ist, lohnt es sich, etwas wie Jotai auszuprobieren.
https://github.com/pmndrs/zustand
https://github.com/pmndrs/valtio
Jotai fühlt sich nach zu viel manueller Boilerplate an, und Valtio hat viel Proxy-„Magie“; persönlich mag ich es zwar, bin mir aber nicht sicher, ob es für ein Team eine gute Wahl ist.
Zustand liegt zwischen Boilerplate und Magie, deshalb habe ich es für ein großes laufendes Projekt ausgewählt.
Als ich vor ein paar Jahren mit der Arbeit an React-Apps begann, waren alle State-Management-Pakete, die ich sah, voll davon, und das ist immer noch so.
Am Ende habe ich, um dem zu entkommen und mich auf die Arbeit zu konzentrieren, meine eigene Lösung gebaut [1], und sie funktioniert in Produktion gut. Schade, dass es keine populäre Option gibt, die ähnlich arbeitet.
[1] https://github.com/facepunch/react-class-model
Das Gute an context hooks ist, dass sie komponierbar sind, und kombiniert mit gecachten Queries kann man ein ziemlich wartbares Pattern aufbauen.
Mich würde interessieren, welche praktische Verbesserung Jotai hier bietet.
Ich hoffe wirklich, nie wieder mit redux oder sagas arbeiten zu müssen.
Die meisten neu eingeführten Funktionen gefallen mir nicht.
Actions und die Hooks
useActionState/useOptimisticwirken wie eine große Komplexitätsfalle. Der Hookusehat einen viel zu wenig aussagekräftigen Namen und verarbeitet keine Promises, die innerhalb einer Komponente erstellt wurden.Es gibt dafür sicher gute Gründe, aber der Ansatz, eine Promise als prop zu übergeben und sie mit dem
use-Hook zu verarbeiten, scheint mehr Komplexität zu erzeugen als die heutigen Workarounds.Server Components wirken ebenfalls ziemlich komplex, und ich bin froh, dass ich mich bisher nicht damit befassen musste.
Die verbesserten Fehlermeldungen bei Hydration-Fehlern sind willkommen, und die Änderung zur Nutzung als provider sowie die Änderung, ref als prop zu verwenden, sind gute Quality-of-Life-Verbesserungen.
Insgesamt mag ich React/Preact für den Bau von SPAs. Mit einer funktionsreichen Komponentenbibliothek wie MUI und einer einfachen State-Management-Lösung wie Preact Signals ist das Erstellen von SPAs ziemlich geradlinig.
Allerdings macht mir Sorgen, wie die Komplexität nach und nach hineinkriecht. Schon beim Lesen der Beschreibungen der neuen Hooks in den Release Notes spürt man eine hohe kognitive Last.
Der React Compiler hingegen ist ein wirklich notwendiges Tool. Dadurch müssen Programmierer typische Optimierungen nicht mehr direkt in Komponenten schreiben, und Komponenten werden weniger komplex.
Ich freue mich auf das Release und die Integration mit Vite und anderen Tools; soweit ich gehört habe, soll auch Preact unterstützt werden.
Die
use-API sollte meiner Meinung nach in etwas umbenannt werden, das sich vom gemeinsamen Präfix der Hooks unterscheidet.Für jemanden, der neu in React-Hooks einsteigt, dürfte es verwirrend sein zu sehen, dass
usebedingt aufgerufen werden darf, normale hooks aber nicht.Es ist wirklich erfreulich, dass das Release verschoben wurde, um das Problem mit parallelem Suspense zu lösen.
Ich habe es noch nicht ausprobiert, bin aber sehr gespannt; insgesamt ist es ein großartiges Release.
Eilmeldung: custom elements werden vollständig unterstützt. Also Web Components.