React: Zehn Jahre "Rethinking Best Practices"

Seite 3: Hooks-API: Abschied von den ungeliebten Klassen

Inhaltsverzeichnis

Mit der Hooks-API bleibt React seinem eigenen Weg treu, Dinge anders als andere zu machen. Im Blog-Post zur Vorstellung der Hooks-API heißt es zur Begründung, warum man nicht weiter auf Klassen setzen wolle, Klassen würden Menschen und Maschinen verwirren. Diese Aussage ist nicht nur aufgrund ihrer Abwegigkeit bemerkenswert. Die Hooks-API ist zwar einfach in der Bedienung und löst viele Probleme der Klassen-API. Allerdings schafft sie auch neue Probleme, die ebenfalls viele Entwicklerinnen und Entwickler verwirren – davon zeugen zahlreiche Blogposts, Tutorials und YouTube-Filmchen zu Hooks wie useEffect, useCallback oder useMemo. Trotz allem hat sich die Hooks-API als Standard-API mittlerweile durchgesetzt.

Die Einführung der Hooks-API ist aber auch ein bemerkenswertes Beispiel für die steten Bemühungen des React-Teams, größtmögliche Abwärtskompatibilität sicherzustellen. Die Einführung der komplett neuen API erfolgte ohne Breaking Changes in der Minor-Version React 16.9. Im zugehörigen Blogpost warnte das Team explizit davor, bestehende Anwendungen sofort auf die neue API umzustellen. Entwicklerinnen und Entwickler sollten die API in ihren Anwendungen lieber Schritt-für-Schritt einführen, zum Beispiel beim Bau neuer Features. Und tatsächlich gilt auch Reacts Klassen-API bis heute nicht als deprecated (veraltet), sondern funktioniert ohne Einschränkungen weiter.

Das React-Release 16.0 vom September 2017 markiert den Start einer neuen internen React-Architektur mit dem Namen Fiber. Damit kann React das Rendern von Komponenten nun kleinteiliger steuern und auch abbrechen, um beispielsweise bestimmten Aktualisierungen der Oberfläche eine höhere (dringendere) Priorität einzuräumen. Erklärtes Ziel dabei ist es, dass sich die Oberfläche für Benutzerinnen und Benutzer reaktiver anfühlt. Auch diesen Umbau konnte das React-Team abwärtskompatibel umsetzen, ohne Anpassungen am Anwendungscode.

Aufgrund der hohen Abwärtskompatibilität empfiehlt sich React nach wie vor auch für den Einsatz in langlebigen Enterprise-Anwendungen. React wirbt explizit damit, dass alle Änderungen stets Tests an "über einhunderttausend Komponenten" bei Meta intern durchlaufen. Neue Releases erscheinen nur mit einer daran erprobten Migrationsstrategie. Der damit verbundene Aufwand führt mitunter zu längeren Releasezyklen. Daher hat das React-Team jüngst bekannt gegeben, einen sogenannten Canary-Release-Kanal einzuführen. Darüber sollen Releases künftig auch schon vorab zur Verfügung stehen, damit sich neue und experimentelle Features vorab auszuprobieren lassen. Per Feature-Toggle können Entwicklerinnen und Entwickler dabei die Neuerungen in eigenen Anwendungen bei Bedarf ein- und ausschalten.

(Bild: react.dev )

Neben der Hooks-API ist mittlerweile auch der Einsatz von TypeScript zum Standard in der React-Entwicklung avanciert, obwohl React selbst nach wie vor nicht mit TypeScript entwickelt wird und das React-Team auch die TypeScript-Typ-Definitionen nicht pflegt. Die React-Entwicklung erfolgt weiterhin mit Flow. Dabei handelt es sich – wie bei TypeScript – um einen statischen Typ-Checker für JavaScript-Code. Das 2012 veröffentlichte TypeScript und das 2014 erschienene Flow lieferten sich anfangs ein Kopf-an-Kopf-Rennen um Features, Verbreitung und Beliebtheit bei Entwicklern und Projekt-Teams. Mittlerweile hat TypeScript dieses Rennen klar für sich entschieden und kommt auch in einer Reihe typischer React-Bibliotheken zum Einsatz. Die React-Code-Basis allerdings wird weiterhin mit Flow entwickelt und es gibt offenbar auch keine Bestrebungen, das zu ändern. Für den Einsatz von TypeScript in einem eigenen React-Projekt spielt das allerdings keine Rolle. Denn das React-Team pflegt die TypeScript-Typen zwar nicht, bietet in Zusammenarbeit mit Microsoft aber Hilfe für Entwicklerinnen und Entwickler, die TypeScript mit React verwenden möchten. Unter anderem kann TypeScript bereits seit dem Release 1.6 JSX-Code überprüfen und in JavaScript-Code übersetzen.

In den zehn Jahren seit Erscheinen von React blieb nicht nur die Frage, welchen Typ-Checker man verwenden sollte, ein immer wieder diskutiertes Thema. Die Anfangszeit von React – und die der Single-Page-Anwendungen – war geprägt vom Kommen und Gehen zahlreicher Bibliotheken und Tools im JavaScript-Umfeld. Der Spruch, es gäbe JavaScript-Bibliotheken, die kürzer haltbar seien als ein Liter frischer Milch, machte die Runde, und die "JavaScript Fatigue" breitete sich aus. Allein das Aufsetzen, Konfigurieren und Pflegen des Build-Tool-Stacks für eine typische React-Anwendung artete schnell zur Vollzeit-Aufgabe aus: Webpack mit seinen unzähligen Loadern und Plug-ins musste zur Babel-Version mit dessen Plug-ins passen, die wiederum zur entsprechenden React-Version passen musste – von TypeScript, ESLint und dem Webpack Development Server ganz zu schweigen.

Viele dieser Probleme löst bislang das Tool create-react-app, das ein funktionsfähiges Projekt-Set-up bereitstellt, sodass sich neue Projekte mittlerweile schnell einrichten lassen. Auch für das mittlerweile sehr populäre Frontend-Build-Tool Vite gibt es ein React Template zum Erzeugen neuer React-Projekte.

Für typische Anforderungen an React-Anwendungen gibt es inzwischen De-facto-Standards. Dazu gehören der React Router für das Routing, SWR oder Tanstack Query für das Arbeiten mit Daten vom Server. Zum Testen von React-Anwendungen hat sich Jest in Kombination mit der react-testing-library weitgehend durchgesetzt. Auch das noch recht neue Browser-Test-Tool Playwright bietet (experimentelle) Unterstützung für das Testen von React-Komponenten.

React hat sich in den letzten Jahren eher langsam, aber doch stetig weiterentwickelt. Releases und neue Features blieben oftmals überschaubar. Legendär war das Major-Release 17, in dessen Ankündigung prominent die Aussage prangte: "No New Features". Auch vom ursprünglichen Claim einer Bibliothek zur Entwicklung von Benutzeroberflächen weicht das Entwicklungsteam bisher nur geringfügig ab: "Die Bibliothek für Web- und native Benutzeroberflächen“.

Was die Zukunft von React angeht, ist allerdings mehr Spannung zu erwarten. In den vergangenen Jahren kamen immer wieder Diskussionen darüber auf, wie sich React-Anwendungen noch effizienter ausführen und neue Anwendungsfälle erschließen lassen. Eine Idee dabei ist, React-Anwendungen ganz oder teilweise zur Laufzeit auf dem Server zu rendern und ganz oder teilweise als fertigen UI-Code zum Client zu senden. Dazu hatte das React-Team Ende 2020 die React Server Components vorgestellt, die bislang noch nicht in einer stabilen Version vorliegen. Im Gegensatz zu den klassisch Client-seitig gerenderten Single-Page-Anwendungen (SPA) benötigt es für diese Komponenten nämlich einen JavaScript-Server zur Laufzeit, den React aber nicht bereitstellt. Stattdessen empfiehlt die Dokumentation für vollständige React-Anwendungen seit Anfang 2023 ganz offen den Einsatz eines sogenannten Fullstack-Frameworks wie Next.js oder Remix. Auch in Diskussionen und Nachfragen zum Beispiel auf GitHub und Twitter bestätigen die Mitglieder des React-Teams diese Einschätzung.

Innerhalb der React-Community herrschte lange Zeit im Großen und Ganzen eine gute Stimmung, mit dieser Entscheidung könnte sich das ändern. Zumindest zurzeit wirkt die Community in dieser Frage gespalten. Für die einen beginnt eine "neue Ära" für React, die jetzt auch den serverseitigen Einsatz ermöglicht. Sogar von React als "PHP++" ist hier unironisch die Rede. Auf der anderen Seite melden sich diejenigen zu Wort, die aus unterschiedlichen Gründen die vorgestellten serverseitigen Features zu kompliziert finden, diese nicht benötigen oder nicht einsetzen wollen und den Fokus lieber auf die Lösung anderer Probleme gelegt gesehen hätten. In diesem Teil der Community ist gar von einem "Angular-2-Moment" die Rede – eine Anspielung auf die Ankündigung der zweiten Major-Version von Angular im Jahr 2014. Damals änderte Google zahlreiche APIs in Angular, bot aber keine Migrationsstrategie von der vorherigen Version an. Mittlerweile trägt die erste Version auch die Bezeichnung AngularJS, während alle Versionen danach Angular heißen, um den Wandel deutlich zu machen.