Startseite / Artikel

Warum das Frontend nach React schwierig ist: State, Effects, Boundaries und KI-Tools

React hat es erleichtert, Benutzeroberflächen zu erstellen, nicht jedoch, sie zu entwerfen. Wo der Zustand liegt, sind verwickelte Effekte, Systemgrenzen sowie von KI erzeugter Code die eigentlichen Aufgaben im Frontend.

Verlag: REACTAPP.TOP9 Min. Lesezeit2114 Wörter

Quellen: React Isn’t the Hardest Part of Frontend Development

Einige Frontend-Entwickler können in zwanzig Minuten eine React-Komponente erstellen, verbringen dann aber die nächsten drei Stunden damit herauszufinden, warum sie nun nicht mehr wartbar ist. Der Schuldige ist weder JSX noch useState, und auch nicht wirklich React selbst. Was die Arbeit am Frontend schwierig macht, sind die Aspekte rund um das Framework: zu wissen, wie sich ein Produkt verhalten sollte, zu entscheiden, wo der Zustand gespeichert werden soll, asynchrone Aufrufe zu koordinieren, Grenzen von Komponenten zu definieren, mit Besonderheiten des Browsers umzugehen, Benutzeroberflächen zugänglich und schnell zu halten sowie Code zu hinterlassen, der auch nach einem halben Jahr noch verständlich ist.

React hat das Erstellen von Benutzeroberflächen einfacher gemacht. Es hat die Frontend-Entwicklung jedoch niemals einfacher gemacht, und der Bereich hat viel zu lange so getan, als wäre das der Fall.

Was React behoben hat und was es unberührt ließ

Bevor React die Oberhand gewann, bestand die Schwierigkeit aus einem anderen Grund. Entwickler bearbeiteten den DOM manuell und verbanden die Ereignishandler nacheinander – dabei hatten sie Schwierigkeiten, den Bildschirm mit den Daten der Anwendung in Einklang zu bringen. Mit wachsenden Anwendungen wurde es immer schwieriger, nachzuvollziehen, wie Benutzeraktionen, Daten und dargestellte Elemente miteinander verbunden sind.

React bot ein nützliches Denkmodell: Die Benutzeroberfläche ist eine Funktion des Zustands. Anstatt dem Browser bei jeder DOM-Änderung Anweisungen zu geben, beschreibt man, wie die Schnittstelle bei einem bestimmten Zustand aussieht. Komponenten legen Grenzen fest, Props liefern explizite Eingaben, der Zustand repräsentiert Daten, die sich im Laufe der Zeit ändern, und die deklarative Darstellung beseitigt viele unbeabsichtigte Komplexitäten. Das war ein echter Fortschritt.

Trotzdem löst ein Framework nur das, wofür es entwickelt wurde. React hat keine Meinung dazu, ob eine Anwendung fünf oder fünfzig Instanzen globaler Zustände benötigt. Es sagt nicht, wann ein Komponenten zu viel tut, ob das Design der API sinnvoll ist, ob die Ladeindikatoren an den richtigen Stellen angezeigt werden oder ob ein Zahlungsablauf für Käufer logisch ist. Und es kann sicherlich nicht entscheiden, was das Produkt tun soll, wenn die Verbindung während einer Anfrage abbricht. All das sind ebenfalls Frontend-Probleme.

Eine gewöhnliche Funktion trifft auf die Realität

Nehmen wir ein einfaches Dashboard. Ein Benutzer öffnet es, die Anwendung lädt Daten, er ändert einen Filter, die Ergebnisse werden aktualisiert, er wählt ein Element aus, ein Modalfeld öffnet sich, er bearbeitet und speichert die Änderungen, der Server antwortet und das Dashboard aktualisiert sich. Daran ist nichts Schwieriges.

Nun fügen wir hinzu, was tatsächlich passiert. Die erste Anfrage fehlschlägt. Der Filter ändert sich, während eine frühere Anfrage noch im Gange ist, und die ältere Antwort erreicht den Empfänger nach der neueren. Das Modalfenster wird über einen Deep Link geöffnet. Die Seite wird mitten in der Bearbeitung aktualisiert. Zwei Tabellen sind geöffnet. Die Sitzung läuft ab. Die API gibt nur teilweise Daten zurück. Der Server akzeptiert eine Änderung, doch der Client sieht die Antwort nie, und der Benutzer klickt zweimal auf „Speichern“. Die Liste enthält 10.000 Zeilen, die Verbindung ist langsam und mobil, die Benutzeroberfläche muss per Tastatur bedient werden, und die Fehlermeldung muss den Nutzern mitteilen, was sie als Nächstes tun können.

Zu diesem Zeitpunkt ist der React-Code der weniger interessante Teil. All das kann mit React umgesetzt werden – und all das kann auch schlecht umgesetzt werden. Viele Entwickler übersehen diesen Unterschied.

Die Aufgabe besteht darin, Komplexität zu verwalten

Die Arbeit eines Frontend-Entwicklers besteht nicht hauptsächlich darin, Komponenten zu schreiben. Es geht vielmehr darum, Komplexität zu verbergen, damit der Benutzer etwas Einfaches sieht – was weitaus schwieriger ist. Eine gut gestaltete Komponente kann aus fünfzig Zeilen bestehen, doch es erfordert eine Reihe von Entscheidungen, um bei fünfzig und nicht bei fünfhundert zu bleiben:

  • Woher die Daten stammen, wer sie verwaltet, wie lange sie bestehen und wer sie ändern darf
  • Was passiert, wenn eine Anfrage fehlschlägt
  • Ob der Zustand bei Navigation oder Neuaufladung beibehalten werden sollte
  • Ob er in der URL, im lokalen Komponentenzustand oder im Server-Cache gespeichert werden sollte
  • Ob zwei Komponenten die Daten selbst teilen sollten oder nur ähnliche Werte eigenständig berechnen sollen

React beantwortet keine dieser Fragen. Der Entwickler tut es stattdessen, und die Antworten häufen sich. Eine schlechte Entscheidung bleibt selten auf einem einzigen Komponenten beschränkt. Sie entwickelt sich zu einem Muster, andere Entwickler kopieren es, und schon bald hat die Anwendung eine konsistente Architektur, die niemand ursprünglich gewählt hat. So werden Frontend-Codebasen problematisch: Entscheidungen stapeln sich, und Reacts Komplexität hat damit nur wenig zu tun.

Zustand als Modellierungsproblem

Eine schnelle Möglichkeit, ein unreifes Frontend-Design zu erkennen, besteht darin, sich seinen Zustand anzusehen. Der häufige Einsatz von useState ist an sich nicht falsch. Das Problem entsteht, wenn der Zustand als Ort zur Speicherung von Werten betrachtet wird und nicht als etwas, das modelliert werden muss. Ein Entwickler sieht einen sich ändernden Wert und greift sofort auf den Hook zurück.

const [value, setValue] = useState(...)

Es wirkt fertig, doch wie der Wert gespeichert wird, ist nicht die eigentliche Frage. Vielmehr geht es darum, ob der Wert überhaupt existieren sollte. Schauen Sie sich dieses Trio an:

const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [fullName, setFullName] = useState("");

Drei State-Objekte enthalten derzeit Informationen, die eigentlich aus zwei abgeleitet werden könnten. React trägt hier keine Schuld – das mentale Modell schon.

Das Gleiche passiert im größeren Maßstab. Teams speichern API-Antworten, gefilterte Kopien dieser Antworten, Ladeindikatoren, berechnete Zahlenwerte, ausgewählte Datensätze, Modalfenster-Indikatoren sowie doppelte Versionen derselben Entität an verschiedenen Stellen. Mit der Zeit kann niemand mehr sagen, welche Kopie als autoritativ gilt – und Fehler entstehen. Ein Komponente ändert eine Kopie, während eine andere eine andere liest. Ein Synchronisierungseffekt versucht, sie in Einklang zu bringen, und ein weiterer Effekt reagiert auf den ersten. Plötzlich enthält der Browser ein kleines verteiltes System. React hat diese Architektur nicht erstellt – das haben die Programmierer getan.

Effects machen das Design sichtbar

Falls eine React-Funktion mehr Kritik erhält als die anderen, dann ist es useEffect, und die Kritik ist oft berechtigt. Doch in der Regel zeigt sich ein architektonisches Problem erst in den Effekten, nicht dort, wo es entsteht.

Stellen Sie sich eine Komponente mit mehreren solchen Effekten vor: Einer lädt Daten, einer synchronisiert den Zustand, einer reagiert auf Änderungen von Props, einer schreibt in den lokalen Speicher, einer sendet Analysedaten und einer setzt etwas zurück, wenn sich eine Bedingung ändert. Jeder Effekt erscheint für sich genommen sinnvoll. Zusammen bilden sie jedoch ein Abhängigkeitsdiagramm, das schwer nachvollziehbar ist. Der Entwickler fügt weitere Abhängigkeiten hinzu, bis der Linter still wird, entfernt einige, weil die Effekte zu oft ausgeführt werden, oder fügt einen booleschen Ref hinzu, um eine doppelte Ausführung zu verhindern. Schließlich funktioniert die Komponente für den getesteten Fall – doch niemand ist ganz sicher, warum.

Das ist kein Mangel von React. Es handelt sich um unklare Verantwortlichkeiten und verwickelte Nebeneffekte, und React bietet einfach einen Ort, an dem sie existieren können.

Der Browser ist ein Knoten in einem größeren System

Die Aufgaben im Frontend werden immer umfangreicher. Eine moderne Anwendung kommuniziert mit APIs und Datenbanken, Authentifizierungssystemen und Analysetools sowie mit Feature Flags, Zahlungsdienstleistern und anderen Drittanbieterdiensten. Hinzu kommen Edge-Funktionen, Serverkomponenten, Hintergrundaufgaben und zunehmend auch von KI unterstützte Dienste. Der Browser ist lediglich ein Teilnehmer in einem weitaus größeren System, weshalb ein Frontend-Entwickler mehr als nur das Rendering verstehen muss – einschließlich dessen, was vor und nach dem Verlassen der Seite mit einer Anfrage geschieht.

Das bedeutet nicht, dass jeder zu einem Backend-Spezialisten werden muss. Es bedeutet vielmehr, dass die alte Trennung zwischen Frontend und Backend an Bedeutung verliert. Jemand, der HTTP nicht kennt, wird letztendlich mit dem Caching zu kämpfen haben. Wer mit Datenbanken nicht vertraut ist, wird Schwierigkeiten haben, Konsistenzfragen zu verstehen, und jemand, der Authentifizierung nicht versteht, wird mit dem Verhalten von Sessions Probleme haben. Race Conditions und Wiederholungsversuche verwirren Entwickler ohne Hintergrundwissen in verteilten Systemen, und diejenigen, die die Nutzer nicht verstehen, liefern elegante Benutzeroberflächen, die niemand nutzen möchte. Das Framework stellt eine einzige Schicht dar.

KI verändert die wirtschaftlichen Aspekte, nicht die schwierigen Teile

AI-basierte Programmierassistenten haben die Kosten für Frontend-Arbeiten verändert. Die Erstellung von Komponenten, Formularen, der Konvertierung von Designs in JSX, Hooks sowie Tests wird alle immer günstiger. Das mag wie eine Bedrohung klingen. Besser ist es, es als Prüfung dafür zu sehen, wo der eigentliche Wert bisher lag. Wenn Ihr Hauptbeitrag darin besteht, schnell JSX einzutippen, stellt die KI ein Problem dar. Wenn es jedoch um das Verständnis von Systemen, Architektur, Produktverhalten, Abwägungen und Nutzern geht, verändert die KI Ihren Arbeitsablauf, lässt den schwierigen Teil unverändert und erhöht vermutlich dessen Bedeutung.

Ein Assistent kann innerhalb von Sekunden drei plausible Versionen einer Funktion erstellen. Die Auswahl daraus ist eine architektonische Entscheidung und keine syntaktische. Er kann eine State-Management-Lösung erstellen, aber sollte dieser State global sein? Er kann eine optimistische Aktualisierung schreiben, aber sollte die App tatsächlich optimistisch handeln? Er kann einen Cache hinzufügen, aber wie sieht die Invalidation-Strategie aus? Er kann einen Effect schreiben, aber sollte dieser Effect überhaupt existieren? Je schneller der Code entsteht, desto wichtiger wird die Urteilsfähigkeit – und das wird voraussichtlich die Arbeit am Frontend in den nächsten Jahren bestimmen.

Starke Frontend-Entwickler denken eher weniger über React nach und mehr über Grenzen. Sie fragen sich, wohin die Verantwortung fällt, und erkennen, wenn ein Komponente zu einer kleinen Anwendung wird. Sie bekämpfen doppelte Zustände, planen bereits vor dem erfolgreichen Ablauf auf Fehler vor, wissen, was die API tatsächlich garantiert, und achten auf unerwartetes Benutzerverhalten. Sie können erkennen, wann eine Abstraktion hilft und wann sie nur Komplexität versteckt. Sie verstehen den Browser, optimieren die Leistung, ohne alles überstürzt zu optimieren, und können vor allem erklären, warum das System so funktioniert. Das ist eine weitaus schwierigere Fähigkeit, die zu automatisieren, und sie hält länger an als das Wissen um die neueste React-API.

Framework-Wissen veraltet

Entwickler sprechen nicht oft genug darüber: Das Wissen über Frameworks hat eine Haltbarkeitsdauer. Die React-API, die vor fünf Jahren erlernt wurde, entspricht nicht mehr ganz dem heutigen Stand. Best Practices ändern sich, Bibliotheken verschwinden, Build-Tools entwickeln sich weiter, Rendering-Strategien evolvieren, Serverfähigkeiten wachsen und neue Frameworks tauchen auf. Die Syntax verändert sich, doch die zugrundeliegenden ingenieurtechnischen Probleme bleiben erstaunlich konstant:

  • Modellierung des Zustands und Übertragung von Daten innerhalb eines Systems
  • Umgang mit Fehlern und Verwaltung asynchroner Aufgaben
  • Vermeidung unnötiger Kopplungen
  • Sicherstellung, dass ein System beobachtbar und eine Schnittstelle zugänglich ist
  • Beherrschung der Komplexität

Diese Probleme haben jQuery, Angular und Backbone überdauert und auch das frühe React-Ecosystem überstanden. Sie werden auch alles, was danach kommt, überdauern. Deshalb ist es ein fragiler Ansatz, Frontend ausschließlich durch Frameworks zu lernen. Lernen Sie das Framework – betrachten Sie es aber nicht als die eigentliche Disziplin.

React könnte eines Tages nicht mehr im Mittelpunkt der Diskussion stehen. Etwas anderes könnte es ersetzen, mehrere Ansätze könnten nebeneinander existieren, oder es könnte weitaus länger dominieren, als erwartet. Das spielt eigentlich keine große Rolle. Entwickler, deren Arbeit stark von React-APIs abhängt, werden diese neu entwickeln müssen, während diejenigen, die verstanden haben, wie Benutzeroberflächen tatsächlich funktionieren, sich anpassen werden.

React ist das Werkzeug, nicht die Kunst

Die Frontend-Entwicklung ging nie im Grunde darum, React zu verwenden. React ist ein sehr gutes Werkzeug zur Erstellung von Frontend-Anwendungen – und bleibt weiterhin ein Werkzeug. Die schwierige Aufgabe besteht darin, zu entscheiden, was dargestellt werden soll: wie die einzelnen Komponenten miteinander interagieren, was passiert, wenn etwas schiefgeht, wo der Zustand gespeichert wird, was im Browser und was auf dem Server läuft, wie das System mit dem Produkt wächst und wie all das vor der Person, die die Anwendung nutzt, verborgen werden kann. Das ist die eigentliche Aufgabe, und JSX ist lediglich die Methode, mit der ein Teil davon typisiert wird.

Je besser die Tools darin werden, Code zu erzeugen, desto weniger wertvoll ist das Erstellen von Code. Das beendet die Softwareentwicklung jedoch nicht, sondern verändert lediglich, worüber Entwickler nachdenken müssen. Jemand, der Komponenten schnell generieren kann, ist nützlich, doch jemand, der beurteilen kann, ob sie überhaupt notwendig sind, noch nützlicher. Dasselbe gilt für API-Integrationen: Eine Erstellung ist nützlich, doch das Erkennen eines Fehlers im Vertragswerk selbst ist noch wertvoller. Ein Entwickler, der eine KI bitten kann, einen Codebase umzustrukturieren, hat Wert, und einer, der beurteilen kann, ob die vorgeschlagene Umstrukturierung das System verbessert, noch mehr.

Deshalb sollte sich niemand Sorgen machen, weil React einfacher wird. Das ist ja das Ziel – schließlich dient ein Framework dazu, überflüssige Arbeit zu reduzieren, und ein erfahrener Entwickler nutzt die eingesparte Zeit für wichtige Probleme.

Verwandte Artikel

  • GLM 5.2 im Claude Code mit einem echten SDK für fünf Dollar testen — Ein fünf-Dollar-Experiment mit OpenRouter: Routing von Claude Code zu GLM 5.2, Überprüfung und Anpassung eines React Native SDKs, welche Kosten jede Aufgabe verursacht hat und wo die Einsparungen enden.
  • Einen Splash Screen zu einer React Native-App für iOS und Android hinzufügen — Schritt für Schritt Anleitung zur Einrichtung eines Splash Screens für React Native auf iOS und Android: Startbildschirm in Xcode, Android-Themen und -Layouts sowie react-native-splash-screen, um das weiße Flackern zu vermeiden.
  • React gewinnt weiterhin, doch die JavaScript-Entwicklung verändert sich — React bleibt in Bezug auf die Verwendung führend, doch die damit verbundenen Ansätze umfassen nun TypeScript, Server-Rendering, Build-Tools, Leistungsoptimierung und KI. Hier erfahren Sie, was Sie als Nächstes lernen sollten.
  • 30 Tipps für React und Redux für skalierbare, wartbare Frontends — Dreißig kurze Tipps zu React und Redux zu Themen wie State, Server-Daten, Hooks, Selectoren, Ordnerstruktur, Testing und Refactoring, geeignet für Anwendungen mit mehr als tausend Komponenten.