Table of Contents
Warum eine modulare React Native Struktur für die Skalierbarkeit unerlässlich ist
Der Aufbau einer React Native-Anwendung, die anmutig skaliert wird, erfordert mehr als nur das Schreiben von sauberem Code. Da Ihre App an Funktionen, Teamgröße und Benutzerbasis zunimmt, kann die anfängliche Ordneranordnung entweder zu einem Engpass oder zu einem Katalysator für nachhaltige Entwicklungsgeschwindigkeit werden. Eine modulare Architektur, bei der die Codebasis in unabhängige, in sich geschlossene Module unterteilt ist, adressiert direkt die Komplexität, die mit der Skalierung einhergeht. Ohne absichtliche Struktur kann selbst ein mittelgroßes Projekt verworrenen Abhängigkeiten, duplizierter Logik und schmerzhaften Merge-Konflikten unterliegen. Eine gut ausgeführte modulare Einrichtung ermöglicht:
- Unabhängige Entwicklung – Teams können an separaten Modulen arbeiten, ohne einander auf die Zehen zu treten.
- Wiederverwendbarkeit über Bildschirme und Apps hinweg – Gemeinsame Komponenten, Hooks und Dienstprogramme leben an bestimmten Orten.
- Isoliertes Testen – Jedes Modul kann isoliert getestet werden, wodurch der Explosionsradius der Regressionen reduziert wird.
- Graduelle Übernahme neuer Muster – Das Refactoring oder die Migration eines einzelnen Moduls ist weit weniger riskant als das Umschreiben der gesamten App.
- Klare mentale Modelle – Neue Ingenieure an Bord sind schneller, wenn sie über die Teile der App nachdenken können, ohne die gesamte Codebasis zu lesen.
In diesem Artikel gehen wir durch eine produktionserprobte Projektstruktur, erklären die Verantwortung jedes Verzeichnisses und diskutieren Muster, die Ihre React Native-Anwendung wartungsfähig halten, wenn sie über ein paar Bildschirme hinauswächst.
Grundprinzipien einer modularen React Native Architecture
Bevor wir in das Ordnerlayout eintauchen, ist es hilfreich, einige Leitprinzipien festzulegen. Diese Grundsätze sollten jede Entscheidung darüber, wo eine Datei platziert werden soll und wie sie ihre Funktionalität offengelegt werden soll, informieren.
Trennung von Bedenken
Jedes Modul sollte einen einzigen, genau definierten Job haben. Zum Beispiel sollte ein nur API-Aufrufe und Datentransformation für benutzerbezogene Endpunkte verarbeiten; es sollte niemals die Benutzeroberfläche rendern. Ebenso sollte eine -Komponente nur Präsentation und Layout behandeln, nicht Daten vom Server abrufen. Diese Trennung macht es trivial, eine Serviceimplementierung auszutauschen oder eine Komponente ohne unbeabsichtigte Nebenwirkungen neu zu gestalten.
Verkapselung
Module sollten eine minimale öffentliche Fläche freilegen. Interne Helferfunktionen, Unterkomponenten oder staatliche Managementmuster, die nur innerhalb eines Moduls relevant sind, sollten privat gehalten werden (z.B. indem sie in einem Unterordner abgelegt oder mit einer Unterstrichkonvention benannt werden).
Explizite Abhängigkeiten
Anstatt sich auf globale Singletons oder implizite Importe zu verlassen (wie „nur von überall importieren), fördert eine modulare Struktur die explizite Injektion von Abhängigkeiten - entweder durch React Context, Redux Store oder einfache Funktionsparameter.
Kohärenz gegenüber dem Übereinkommen
Jedes Team hat zwar Präferenzen, aber sobald Sie eine Konvention gewählt haben (Dateinamen, Ordnerverschachtelung, Exportstil), müssen Sie diese konsequent durchsetzen. Tools wie ESLint-Plugins zum Importieren von Sortierungen und Ordnerstrukturverkleidungen können dabei helfen, dies zu automatisieren.
Empfohlene Projektstruktur: Ein Deep Dive
Die folgende Struktur wurde in Produktions-React Native-Apps getestet, die von einer Handvoll Bildschirmen bis zu dreistelligen Feature-Modulen reichen. Sie gleicht Einfachheit mit der Fähigkeit zur Skalierung aus. Wir gehen von einer TypeScript-Codebasis aus – wenn Sie einfaches JavaScript verwenden, gelten die gleichen Prinzipien.
my-react-native-app/
├── assets/
│ ├── fonts/
│ ├── images/
│ └── lottie/
├── src/
│ ├── components/ # Reusable UI primitives
│ ├── screens/ # Top-level route components
│ ├── navigation/ # Navigation configuration & linking
│ ├── services/ # API clients, data-fetching logic
│ ├── state/ # Global state (Redux, Zustand, etc.)
│ ├── hooks/ # Custom React hooks
│ ├── utils/ # Pure utility functions & constants
│ ├── types/ # TypeScript interfaces & enums
│ ├── config/ # Environment variables, feature flags
│ └── theme/ # Colors, typography, spacing tokens
├── tests/ # Integration & end-to-end tests
├── app.json
├── package.json
└── tsconfig.json
Lassen Sie uns den Zweck jedes Verzeichnisses untersuchen und was darin gehört.
– Wiederverwendbare UI-Bausteine
Dieser Ordner enthält Komponenten, die nicht an einen bestimmten Bildschirm oder eine bestimmte Funktion gebunden sind. Beispiele sind , , , , , . Sie sollten vollständig generisch sein: Sie erhalten Requisiten und rendern die Benutzeroberfläche ohne Kenntnis der Geschäftslogik der App. Wenn Sie sich dabei befinden, dass Sie eine Requisiten wie zu einem generischen hinzufügen, benötigen Sie wahrscheinlich eine spezifischere Komponente. Halten Sie diese Komponenten klein und komponieren Sie sie mithilfe von Kindern oder rendern Sie Requisiten. Stellen Sie sicher, dass Komponenten mit Bildschirmlesern funktionieren und respektieren Sie die Systemschriftartskalierung.
Ein häufiger Fehler ist das Einstülpen aller möglichen UI-Stücke in einen flachen Ordner . Wenn die Bibliothek wächst, sollten Sie die Gruppierung verwandter Komponenten in Unterordnern in Betracht ziehen:
- – Die wahrhaft universellen Widgets.
- – Eingabefelder, Kontrollkästchen, Radio-Buttons.
- – Datenvisualisierungskomponenten.
Jede Komponente sollte eine eigene Testdatei (z. B. ) und möglicherweise eine Storybook-Story für visuelle Regressionstests haben.
– Top-Level Page Components
Bildschirme sind die Komponenten, die direkt auf Routen in Ihrem Navigationsstack abbilden. Jeder Bildschirm besteht aus einer Mischung aus wiederverwendbaren Komponenten und funktionsspezifischen Komponenten, die im Bildschirmordner (oder einem zusammengehörigen Verzeichnis) leben. Der Bildschirm selbst sollte dünn sein: Er holt Daten ab, übergibt Requisiten nach unten und verwaltet das Layout auf Bildschirmebene. Vermeiden Sie es, komplexe Geschäftslogiken hier zu platzieren; delegieren Sie stattdessen Dienste und Hooks.
Wenn Sie mehrere Bildschirme haben, können Sie sie nach Feature-Domain gruppieren:
- – LoginScreen, RegisterScreen, ForgotPasswordScreen
- – MainScreen, AnalyticsScreen, ReportsScreen
– Routing & Deep Linking
Hier richten Sie Ihren React Navigation Stack, Tab, Schublade und Verknüpfungskonfigurationen ein. Wenn Sie die Navigation von Bildschirmen und Komponenten getrennt halten, können Sie den gesamten Navigationsfluss ändern (z. B. einen Stack-Navigator gegen einen Modal-Navigator austauschen), ohne einen Bildschirmcode zu berühren. Typische Dateien:
- – Der Navigator auf höchster Ebene, der entscheidet, welcher Stapel angezeigt werden soll (auth vs. main).
- – Die untere Tab-Leiste.
- – Deep Link Konfigurationsobjekt für React Navigation.
- – Ein Ref zum Navigationscontainer für die Verwendung außerhalb von Komponenten (z. B. in Diensten).
Wenn Ihre App Deep Linking von Push-Benachrichtigungen oder universellen Links unterstützt, ist dieser Ordner die einzige Quelle der Wahrheit für die Routenzuordnung.
– API Calls & Business Logic
Dienste kapseln die gesamte Kommunikation mit externen Systemen ein: REST-APIs, GraphQL, localStorage, Push-Benachrichtigungsregistrierung usw. Ein Dienst ist typischerweise eine Klasse oder eine Reihe von Funktionen, die Parameter und Rückgabeversprechen annehmen.
- – Login, Logout, Token Refresh.
- – fetchProfile, updateProfile, uploadAvatar.
- – trackEvent, identifyUser.
Dienste sollten React oder keinen UI-Code importieren, sie können jedoch Helferfunktionen von und Typen von verwenden, was sie mit reinen Unit-Tests testbar und in Integrationstests leicht zu verspotten macht.
Für das Datenabrufen bevorzugen viele Teams jetzt React Query oder SWR, die das Caching und Background Refetching verwalten. In diesen Fällen können Sie die Abfrage-Hooks innerhalb von platzieren, aber die zugrunde liegenden API-Aufrufe sind immer noch in aktiv.
– Globales Staatsmanagement
Dieses Verzeichnis enthält die von Ihnen gewählte globale Zustandslösung: Redux Store, Redux Toolkit Slices, Zustand Stores oder Recoil Atome. Bewahren Sie jeden Store Slice oder Kontextanbieter in einer eigenen Datei auf, benannt nach Domäne. Beispiel für Redux Toolkit:
- - configurationStore, root reducer.
- – benutzerdefinierte Middleware (z.B. Protokollierung, Analyse).
Wenn Sie React Context verwenden, platzieren Sie hier Ihre Provider und Kontext-Hooks. Wenn Sie den globalen Zustand isoliert halten, wird eine versehentliche Vermischung von UI-Logik mit Zustandslogik verhindert.
- Custom Hooks
Wiederverwendbare Zustandslogik in benutzerdefinierten Hooks einkapseln. Beispiele:
- (verfolgen Sie, ob die App im Vordergrund / Hintergrund ist)
- (umhüllt Auth Zustand und Service-Anrufe)
Haken, die für einen einzelnen Bildschirm spezifisch sind, sollten mit diesem Bildschirm zusammenlebt, nicht im globalen Ordner
– Reine Utilities & Konstanten
Dieser Ordner enthält Funktionen oder Konstanten, die rein und zustandslos sind und nicht von React oder einem Anwendungszustand abhängen.
- (API-Basis-URL, Timeout-Werte, Feature-Flag-Schlüssel)
Halten Sie diese klein und zweckgebunden. Vermeiden Sie "Küchenspüle" -Dateien, die nicht verwandte Hilfsprogramme enthalten. Wenn Sie mehr als eine Handvoll Helfer finden, zerlegen Sie sie in separate Dateien.
– TypeScript Type Definitionen
Zentralisieren Sie hier Ihre TypeScript-Schnittstellen, Typ-Aliase und Enums.
- – Parameterlisten für jeden Navigator.
- – User, UserProfile, UserSettings types.
- – generische API-Antworthülle, Paginierungstypen.
- – kundenspezifische markenspezifische Typen.
Die Verwendung einer einzigen Wahrheitsquelle für Typen verhindert Inkonsistenzen und erleichtert das Refactoring bei Änderungen des Backend-Schemas.
– Umgebung & Feature Flags
React Native Apps benötigen oft eine unterschiedliche Konfiguration pro Umgebung (Entwicklung, Staging, Produktion). Behalten Sie diese Logik hier, oft mit oder Umgebungsvariablen.
- – eine Karte von booleschen Flaggen, um Funktionen in der Entwicklung zu aktivieren/deaktivieren.
- Design Tokens & Theming
Eine Theme-Datei exportiert Konstanten für Farben, Typografie, Abstand, Schatten und Haltepunkte. Viele Teams verwenden eine Bibliothek wie oder , die diese Tokens verbrauchen.
- – Standard-Theme-Objekt.
- Statische Ressourcen
Speichern Sie alle statischen Dateien, die bedingt oder zum Build-Zeit importiert werden. Dies umfasst Schriftarten, Bilder, Lottie-Animationen, JSON-Dateien und ähnliches. Strukturierung nach Ressourcentyp hilft Ihrem Bundler (Metro), sie richtig zu lösen.
– Integration & E2E Tests
Während Unit-Tests neben dem von ihnen getesteten Code (z. B. ) live sein sollten, gehören Integrations- und End-to-End-Testdateien hier hin. Verwenden Sie Detox oder Appium für E2E und erstellen Sie Testprofile für verschiedene Benutzerreisen. Bewahren Sie Testdaten und Geräte in Unterordnern auf, um sie wiederverwendbar zu machen.
Umsetzung der Struktur in der Praxis
Nachdem Sie die Theorie verstanden haben, finden Sie hier einen praktischen Schritt-für-Schritt-Ansatz zum Einrichten dieser Struktur in einem neuen oder bestehenden React Native-Projekt.
Schritt 1: Initialisieren Sie den Ordnerbaum
Erstellen Sie die Verzeichnisstruktur mit Ihrem Terminal oder Ihrer IDE. Verwenden Sie für ein neues Projekt zuerst , löschen Sie dann den Standard und erstellen Sie ihn als einen Einstiegspunkt, der importiert.
Schritt 2: Starten Sie die Navigation frühzeitig
Installieren Sie React Navigation und erstellen Sie ein in . Definieren Sie Ihre ersten Bildschirmrouten.
Schritt 3: Erstellen Sie das Thema und die Konstanten
Bevor Sie irgendwelche Komponenten schreiben, legen Sie Ihre Design-Token in und Konstanten in fest, was sicherstellt, dass jeder Entwickler vom ersten Tag an konsistente Werte verwendet.
Schritt 4: Bauen Sie eine wiederverwendbare Komponente
Wählen Sie eine einfache Komponente wie und legen Sie sie in ab. Schreiben Sie die Testdatei. Exportieren Sie sie und verwenden Sie sie in einem Platzhalterbildschirm. Dies bestätigt, dass Ihre Build-Pipeline mit der Ordnerstruktur funktioniert.
Schritt 5: Erstellen eines Service Layers
Wenn Ihre App mit einer API kommuniziert, erstellen Sie in ein oder mit Basis-URL und Interceptoren.
Schritt 6: Hinzufügen von State Management
Entscheiden Sie sich für ein State Tool (Redux Toolkit, Zustand, etc.) und richten Sie es in ein.
Schritt 7: Refactoring Existing Code Schrittweise
Wenn Sie ein bestehendes Projekt migrieren, verschieben Sie Dateien ein Verzeichnis nach dem anderen, beginnend mit den stabilsten Teilen (Thema, Konstanten, Dienste). Verwenden Sie Tools wie und halten Sie Ihre Tests grün. Es ist besser, eine Woche mit Refactoring zu verbringen, als monatelang mit einer verworrenen Codebasis zu leben.
Erweiterte Überlegungen für groß angelegte Anwendungen
Da Ihr Team und Ihre Codebasis über 20 bis 30 Entwickler hinauswachsen, muss die grundlegende Schicht-basierte Struktur möglicherweise erweitert werden.
Feature-Based Module (Feature Folders)
Anstatt nach technischen Rollen (Komponente, Service, Bildschirm) zu trennen, gruppieren Sie jede Datei, die sich auf eine Geschäftsdomäne bezieht, in einem einzigen Ordner auf oberster Ebene.
src/
features/
auth/
components/
screens/
services/
state/
hooks/
types/
profile/
components/
screens/
services/
state/
hooks/
types/
shared/
components/
utils/
hooks/
Dieser Ansatz hält jedes Feature vollständig gekapselt und leichter zu argumentieren. Es funktioniert am besten, wenn Features wirklich unabhängig sind und von separaten Teams entwickelt werden können. Der Nachteil ist, dass es zu einer Duplikation von generischen Komponenten führen kann, wenn es nicht diszipliniert ist, gemeinsame Teile zu FLT:93 zu verschieben.
Monorepos mit Shared Libraries
Wenn Sie mehrere React Native Apps (Customer-facing, Admin, White-Label) pflegen, sollten Sie ein Monorepo in Betracht ziehen, das mit Nx oder Turborepo verwaltet wird. Platzieren Sie freigegebene React Native Komponenten, Hooks und Dienstprogramme in einer Bibliothek, die beide Apps verbrauchen. Dies nutzt die modulare Struktur über Apps hinweg und erzwingt eine einzige Quelle der Wahrheit für Ihr Designsystem. Die oben beschriebene Haupt-App-Struktur gilt weiterhin, aber der Ordner kann einfach aus der freigegebenen Bibliothek reexportieren.
Code Splitting & Ampere; Lazy Loading
React Native unterstützt keine dynamischen Importe out-of-the-box, aber Bibliotheken wie und Hermes-Unterstützung können helfen. Strukturieren Sie Ihre Bildschirme so, dass jeder Bildschirm ein separates, faul geladenes Modul ist. Dies reduziert die anfängliche Bundle-Größe und verbessert die Startzeit für große Apps.
Best Practices für langfristige Wartung
Selbst die beste Ordnerstruktur wird ohne disziplinierte Gewohnheiten scheitern. Integrieren Sie diese Praktiken in Ihren täglichen Workflow.
- Erzwingen Sie mit Linting – Verwenden Sie Regeln wie , um versehentliche modulübergreifende Importe zu verhindern, z. B. sollte ein Dienst niemals eine Komponente importieren.
- Write tests along code – Jeder Modulordner sollte einen -Unterordner oder eine co-lokalisierte .test-Datei haben. Testdienste isoliert testen, Hooks mit testen und Bildschirme mit einem Mock-Store testen.
- Behalte Abhängigkeiten explizit – Vermeiden Sie es, sich auf implizite globale Anbieter zu verlassen. Wenn ein Bildschirm den Auth-Zustand benötigt, geben Sie ihn über Requisiten oder durch einen Kontext, der klar dokumentiert ist.
- Use TypeScript strict mode – Setzt in tsconfig. Dies fängt Null-Sicherheitsprobleme auf und fördert die korrekte Eingabe von Modulgrenzen.
- Überprüfen Sie den Zustand der Struktur vierteljährlich – Wenn Features hinzugefügt werden, stellen Sie möglicherweise fest, dass Ordner zu groß werden. Budget Zeit, um einen einzelnen Komponentenordner in Unterordner aufzuteilen oder ein neues Feature-Modul zu extrahieren.
- Dokumentieren Sie Ihre Konventionen – Erstellen Sie eine , die die Ordnerstruktur, Namenskonventionen und Importregeln erklärt.
Für weitere Informationen bietet die React Native Architecture Documentation Anleitungen zum Threading, Bridge und TurboModules – obwohl nicht direkt über die Projektstruktur, hilft das Verständnis der zugrunde liegenden Plattform dabei, intelligentere Modularitätsentscheidungen zu treffen. Überprüfen Sie auch die Redux Toolkit Documentation zur Strukturierung der Zustandslogik und In React Navigation denken, um eine skalierbare Navigation zu entwerfen.
Schlussfolgerung
Eine modulare React Native-Projektstruktur ist keine Wunderwaffe – sie erfordert bewusste Anstrengungen zum Entwerfen und Pflegen. Aber die Auszahlung ist immens: schnelleres Onboarding, sichereres Refactoring, weniger Merge-Konflikte und die Fähigkeit, Ihre App zu skalieren, ohne sie von Grund auf neu zu schreiben. Beginnen Sie mit dem oben beschriebenen grundlegenden Layer-basierten Layout, erzwingen Sie die Trennung von Bedenken beim Linting und Testen und entwickeln Sie sich zu Feature-basierten oder Monorepo-Mustern, wie es Ihre Bedürfnisse erfordern. Ihr zukünftiges Selbst - und Ihre Mitentwickler - werden es Ihnen danken.