Refactoring von React Native: von 800 Zeilen auf 100 Zeilen
Es gibt einen Moment, in dem du eine Datei öffnest und das Gewicht der technischen Schuld physisch spürst. Mein Hauptbildschirm hatte 800 Zeilen. Eine einzige Datei. Geschäftslogik, UI-Rendering, Zustandsverwaltung, API-Aufrufe – alles vermischt in einer monolithischen, unpflegbaren Komponente. Und das war kein Einzelfall: Ich hatte 16 Bildschirme im gleichen Zustand.
Was ich dir hier erzählen werde, ist, wie ich eine chaotische Codebasis in eine saubere Architektur verwandelt habe. Nicht durch eine spektakuläre Revolution, sondern durch ein methodisches Refactoring, Bildschirm für Bildschirm, Fehler für Fehler.
Wichtige Punkte zum Merken:
- Ein benutzerdefinierter Hook pro Bildschirm trennt die Geschäftslogik vom UI-Rendering
- Das Muster "Orchestrator + Unterkomponenten" reduziert Dateien von 800 auf 100 Zeilen
- ESLint mit strengen Regeln (keinany, awaited Promises) eliminiert stille Fehler
- Technische Schuld ist ein realer Kostenfaktor, messbar in Zeit, Fehlern und Motivation
- Bildschirm für Bildschirm refaktorieren ermöglicht kontinuierliche Lieferung, ohne Bestehendes zu zerstören
Warum ist eine 800-Zeilen-Komponente ein Problem?
Die offensichtliche Antwort: Sie ist unleserlich. Aber das wahre Problem ist heimtückischer. Eine monolithische Komponente:
- Versteckt Fehler: Wenn alles in derselben Datei ist, sind Nebenwirkungen unvorhersehbar. Das Ändern der Filterlogik kann die Übergangsanimation zerstören, ohne dass du verstehst, warum.
- Verlangsamt die Entwicklung: Jede Änderung erfordert das Verständnis der gesamten Datei. Du verbringst 20 Minuten mit "Lesen", bevor du 5 Zeilen schreiben kannst.
- Macht das Debugging unmöglich: Wenn ein Fehler auftritt, hast du 800 Zeilen Verdächtige. Keine klare Grenze zwischen den Verantwortlichkeiten.
- Beeinträchtigt die Motivation: Jeden Morgen eine monströse Datei zu öffnen, das belastet. Das ist die Art von unsichtbarer Reibung, die ein Indie-Projekt verlangsamt.
"Du bist allein, wer wird diesen Code lesen?" Ich. Ich in drei Monaten, wenn ich vergessen habe, warum dieser Bildschirm das tut, was er tut. Technische Schuld ist keine Metapher. Es ist ein realer Kostenfaktor, der in Zeit, Fehlern und Motivation bezahlt wird.
Welche Zerlegungsstrategie sollte man anwenden?
Ich habe die 16 Bildschirme nach einer konsistenten Struktur refaktorisiert. Das Muster ist einfach, aber mächtig:
1. Ein benutzerdefinierter Hook für die Geschäftslogik
Jeder Bildschirm hat seinen Hook: useTaskDetail, useFeedScreen, useGroupScreen... Der Hook kapselt die gesamte Logik: Daten laden, Zustandsverwaltung, Callbacks. Die Komponente macht nur JSX-Rendering.
Vorher:
// TaskDetailScreen.tsx - 800 Zeilen
const TaskDetailScreen = () => {
const [task, setTask] = useState(null);
const [loading, setLoading] = useState(true);
const [editing, setEditing] = useState(false);
// ... 50 weitere useState
// ... 200 Zeilen useEffect
// ... 300 Zeilen Handler
// ... 250 Zeilen JSX
}
Nachher:
// TaskDetailScreen.tsx - 100 Zeilen
const TaskDetailScreen = () => {
const { task, loading, editing, handlers } = useTaskDetail();
return (
<TaskDetailHeader task={task} onEdit={handlers.edit} />
<TaskDetailBody task={task} />
<TaskDetailActions handlers={handlers} />
);
}
Der Hook useTaskDetail hat 200 Zeilen. Die Unterkomponenten haben jeweils 50 bis 100 Zeilen. Insgesamt sind das mehr Zeilen als zuvor – aber jede Datei ist isoliert verständlich.
2. Unterkomponenten für das Rendering
Jeder visuelle Bereich des Bildschirms wird zu einer dedizierten Komponente: TaskDetailHeader, TaskDetailBody, TaskDetailActions. Jede empfängt ihre Props und kennt nur ihre Verantwortung.
Dieses Muster ist direkt inspiriert vom offiziellen Thinking in React. Es ist nicht neu, aber es ist unglaublich, wie sehr man es vergisst, wenn man es eilig hat, etwas zu liefern.
3. Eine Hauptkomponente für die Orchestrierung
Die Hauptkomponente wird zu einem 100-Zeilen-Orchestrator: Sie ruft den Hook auf, verteilt die Props an die Unterkomponenten und verwaltet das globale Layout. Nichts weiter.
Wie kommt man von 71 auf 0 ESLint-Fehler?
Parallel zum Refactoring der Bildschirme habe ich ESLint mit strengen Regeln auf dem Backend ausgeführt. Ergebnis: 71 Fehler.
Die Versuchung: Regeln deaktivieren, die die meisten Fehler verursachen. Das tun 90% der Entwickler. Ich habe das Gegenteil getan: Ich habe jeden Fehler einzeln korrigiert.
Die wirkungsvollsten Korrekturen
Eliminierung von any: Jedes any in TypeScript ist eine Zeitbombe. Es kompiliert, besteht Tests, stürzt aber in der Produktion ab, wenn ein unerwarteter Wert ankommt. Ich habe jedes any durch einen expliziten Typ ersetzt. Einige Fälle erforderten die Erstellung dedizierter Schnittstellen, aber das Ergebnis ist ein selbstdokumentierender Code.
Promises korrekt awaited: Asynchrone Aufrufe ohne await, die stillschweigend fehlschlugen. Keine Fehler, keine Warnungen – nur falsches Verhalten in der Produktion. ESLint hat 12 Fälle von nicht-awaited Promises erkannt. 12 potenzielle Fehler in einer Stunde eliminiert.
Unbenutzte Variablen: Vergessene Imports, deklarierte, aber nie verwendete Variablen. Keine Fehler, aber Rauschen, das den Code schwerer lesbar macht. Jede unnötige Zeile ist eine Ablenkung für dein "zukünftiges Ich", das versucht, den Code zu verstehen.
Soll man alles auf einmal oder schrittweise refaktorisieren?
Schrittweise. Immer schrittweise. Ein "Big Bang Refactoring", bei dem du alles in einer Woche neu schreibst, ist das Rezept für eine Katastrophe für einen Solo-Entwickler. Du zerstörst alles, kannst nichts mehr liefern, und wenn ein kritischer Fehler in der Produktion auftritt, kannst du ihn nicht schnell beheben.
Meine Methode:
- Wähle den schmerzhaftesten Bildschirm (den, den du am meisten fürchtest zu öffnen)
- Extrahiere zuerst den benutzerdefinierten Hook (die Logik, nicht das Rendering)
- Teste, ob alles noch genau wie zuvor funktioniert
- Extrahiere die Unterkomponenten einzeln
- Liefere den refaktorisierten Bildschirm, gehe zum nächsten über
Jeder refaktorisierte Bildschirm dauerte zwischen 2 Stunden und einem halben Tag. Die komplexesten (der Feed, der Gruppenbildschirm) dauerten einen ganzen Tag. Aber in jedem Schritt blieb die App funktionsfähig und lieferbar.
Dieser Workflow ähnelt dem, was Martin Fowler beschreibt in seinem Buch über Refactoring: kleine, inkrementelle und immer reversible Transformationen.
Welche konkreten Vorteile nach dem Refactoring?
Nach zwei Wochen Arbeit:
- 16 Bildschirme refaktorisiert: Jeder folgt dem gleichen Muster (Hook + Unterkomponenten + Orchestrator)
- 0 ESLint-Fehler auf dem Backend (gegenüber 71 zuvor)
- Verständniszeit um das 3-fache reduziert: Einen Bildschirm öffnen und verstehen, was er tut, dauert 2 Minuten statt 10
- Fehler reduziert: Die folgenden 3 Wochen waren die stabilsten des Projekts
- Motivation wiedergefunden: Morgens eine saubere Datei zu öffnen, das ändert alles
Der am wenigsten messbare, aber wichtigste Gewinn: das Vertrauen. Nach dem Refactoring hatte ich keine Angst mehr, einen Bildschirm zu ändern. Ich wusste genau, wo sich alles befand, welche Abhängigkeiten es gab und was eine Änderung beeinflussen würde.
Wie beeinflusst technische Schuld ein Solo-Projekt?
Technische Schuld in einem Solo-Projekt hat spezifische Auswirkungen, die man im Team nicht findet:
Kein Sicherheitsnetz. Im Team kann ein Kollege deinen Code überprüfen, eine Regression erkennen oder einen Fehler beheben, wenn du abwesend bist. Allein, wenn dein Code unverständlich ist, zahlst du – und nur du – den Preis.
Der kumulative Effekt. Jede Abkürzung, die du heute nimmst, multipliziert sich. Ein any hier, ein // TODO: fix later dort, und in wenigen Monaten hast du eine Codebasis, in der jede Änderung dreimal länger dauert, als sie sollte.
Die Demotivationsspirale. Schmutziger Code → Fehler → Frustration → schnelle Patches → noch schmutzigerer Code. Ich habe diese Spirale bei anderen Projekten gesehen. Das Refactoring hat sie abrupt durchbrochen.
Das ist die gleiche Logik, die ich bei der Restrukturierung der Datenbank und dem Sicherheitsaudit anwende: Jetzt Zeit investieren, um später exponentiell mehr zu gewinnen.
Welche ESLint-Regeln sind für ein React Native Projekt empfehlenswert?
Hier sind die Regeln, die den größten Einfluss auf die Codequalität von TAMSIV hatten:
@typescript-eslint/no-explicit-any: Verbietetany. Nicht verhandelbar.@typescript-eslint/no-floating-promises: Erkennt nicht-awaited Promises. Kritisch, um stille Fehler zu vermeiden.@typescript-eslint/no-unused-vars: Eliminiert Rauschen durch toten Code.react-hooks/exhaustive-deps: Überprüft Hook-Abhängigkeiten. Wesentlich in React Native.no-console: Erzwingt die Verwendung eines Loggers anstelle vonconsole.login der Produktion.
Aktiviere sie alle im Modus "error", nicht "warn". Eine Warnung wird ignoriert. Ein Fehler wird behoben.
Was ich aus dieser Refactoring-Woche gelernt habe
Diese Woche war die beste des Projekts. Nicht die aufregendste – keine sichtbaren Features für den Benutzer. Aber die wirkungsvollste für die Zukunft. Jedes Feature, das ich danach gebaut habe – das Gamification-System, die hierarchischen Gruppen, der kollaborative Kalender – profitierte von dieser sauberen Architektur.
Wenn du Solo-Entwickler bist und ein Refactoring aufschiebst, weil "es nichts Sichtbares liefert", hör auf damit. Es ist die rentabelste Investition, die du tätigen kannst. Nicht glamourös, nicht aufregend, aber grundlegend notwendig.
Die beste Woche des Projekts. Und ich würde es ohne zu zögern wiederholen.
FAQ
Wie lange dauert ein Refactoring von 16 Bildschirmen?
Für mich etwa zwei Wochen Vollzeit. Jeder Bildschirm dauert je nach Komplexität zwischen 2 Stunden und einem Tag. Der einfachste Bildschirm (ein grundlegendes Formular): 2 Stunden. Der komplexeste (der Feed mit Gamification): ein ganzer Tag.
Führt Refactoring zu neuen Fehlern?
Das ist das Hauptrisiko. Um es zu minimieren, habe ich einen Bildschirm nach dem anderen refaktorisiert und jeden Flow manuell getestet, bevor ich zum nächsten überging. Während der zweiwöchigen Refactoring-Phase traten keine größeren Regressionen auf.
Sollte man Tests schreiben, bevor man refaktorisiert?
Im Idealfall ja. In der Realität würde bei einem Solo-Projekt mit 16 zu refaktorisierenden Bildschirmen das Schreiben umfassender Tests vor dem Refactoring die Zeit verdoppeln. Ich habe mich für strenge manuelle Tests und automatisierte Tests nach dem Refactoring auf der sauberen Architektur entschieden.
Funktioniert das Muster Hook + Unterkomponenten für alle Bildschirme?
Ja, mit Variationen. Einige einfache Bildschirme benötigen keine Unterkomponenten – der Hook allein genügt. Andere komplexe Bildschirme haben mehrere Ebenen von Unterkomponenten. Das Prinzip bleibt dasselbe: Logik und Rendering trennen.
Verlangsamt ESLint die tägliche Entwicklung?
Die ersten Stunden ja – die Zeit, um bestehende Fehler zu beheben. Danach ist es umgekehrt: ESLint beschleunigt die Entwicklung, indem es Fehler erkennt, noch bevor die App gestartet wird. Es ist wie ein Co-Pilot, der deine Flugbahn in Echtzeit korrigiert.