16. Sep 2024
Lesedauer 23 Min.
Apps mit Fluent UI React Native programmieren
Komponentenbasierte Apps mit Fluent/FAST, Teil 6
React-Entwickler erstellen Apps mit Fluent UI React Native von Microsoft für Android, iOS, macOS und Windows.

Das Open-Source-Team von Meta (ehemals Facebook) stellt das UI-Framework React Native [1] zur Programmierung von Apps für eine Vielzahl von Plattformen bereit. Microsoft nutzt React Native für das hauseigene Design-System Fluent [2], um Anwendern in einer App über Fluent UI React Native höherwertige Benutzererfahrungen für Android, iOS, macOS und Windows verfügbar zu machen.
Prinzipien der Programmierung mit React Native in Abgrenzung zu React
Das Fundament von React Native bildet der in React [3] vorhandene Ansatz einer komponentenorientierten Programmierung. React (auch React.js oder ReactJS genannt) entspricht einer Bibliothek für Benutzeroberflächen, aus deren Elementen der Programmierer das User-Interface hierarchisch aufbaut. Die Spezifikation der UI-Komponenten erfolgt in einer speziell für React definierten Syntax: JSX (JavaScript Extension), manchmal auch JavaScript XML genannt. Bei JSX handelt es sich um eine Auszeichnungssprache (Template Language) für Komponenten, angelehnt an HTML/XML-Tags. Mit JSX erfolgt die Definition der Komponenten rein deklarativ – deren Darstellung in der App übernimmt die React-Laufzeitumgebung.Die React-Native-Welt kennt zwei verschiedene Klassen von Komponenten: Native und Core Components. Grundsätzlich kann ein React-Native-Programmierer alle auf der jeweiligen Plattform (Android, iOS) verfügbaren Views direkt in JavaScript nutzen. Derart nativ programmierte Komponenten bezeichnet die React-Native-Community als Native Components. Das Framework greift auf diese zur Laufzeit direkt zu – woraus eine bessere Performance für die App resultiert.Im Unterschied dazu handelt es sich bei den Core Components um eine Menge von über das React-Native-Framework selbst bereitgestellten Komponenten, die ein Programmierer mit JSX im Quellcode anspricht und unmittelbar verwendet. Zusätzlich von der React-Native-Community bereitgestellte Komponenten nennt man Community Components.React hat das Konzept des Virtual DOM (Document Object Model) eingeführt, damit aus Änderungen der Benutzeroberfläche nicht ständig ein Performance-intensives Rendering des kompletten DOM im Browser stattfinden muss. Allerdings kommt dieses Konzept der selektiven Aktualisierung des DOM von React bei React Native nicht zum Einsatz, da React Native eine eigene Architektur für die Ausführung der App besitzt. Im Unterschied zu React zielt React Native zum Übersetzungszeitpunkt darauf ab, den Quellcode der App in nativen Code der jeweiligen mobilen Plattform zu überführen. Diese Vorgehensweise stellt sicher, dass React Native keinerlei Abhängigkeiten zu irgendeiner Plattform besitzt.React bringt auf jeder Plattform eine Single-Page-App (SPA) über deren lokalen Browser zur Ausführung: Zum Startzeitpunkt fordert der Browser die App als ein vollständiges HTML-Dokument vom Server per Download an. Anschließend benötigte weitere Inhalte lädt die SPA dynamisch nach. Dadurch reduziert sich die Serverlast, die App nutzt die lokale Verarbeitungsstärke des Clients und ermöglicht so auch eine Offline-Unterstützung.Im Unterschied zu React kommt bei React Native auf einer mobilen Plattform stets eine native App zum Einsatz. Das Laufzeitsystem von React Native überführt den mit JSX programmierten JavaScript-Code auf dem Endgerät in dessen native UI-Elemente, auch Views genannt, und zeigt diese an.Arbeitsweise der React-Native-Architektur im Überblick
Die Übersetzung und Ausführung einer React-Native-App zielt im Wesentlichen darauf ab, die Performance des Entwicklungspfads (den internen Workflow von React Native) und der App selbst zu optimieren. Dazu teilt React Native die Übersetzung und Ausführung der App auf verschiedene JavaScript-Threads auf. Diese gehören als Bestandteile zur Architektur von React Native (Bild 1).
React Native besitzt eine auf Threads basierende Architektur für die Ausführung von Apps auf einer mobilen Plattform (Bild 1)
Autor
Zu den wichtigsten JavaScript-Threads des Laufzeitsystems zählen:
- UI/Native/Main-Thread: Erzeugt für die React-Native-Komponenten den nativen Quellcode der jeweiligen Mobile-Plattform (Java/Kotlin auf Android oder Objective-C/Swift auf iOS) und kommuniziert mit dem JavaScript/JS-Thread. Dabei führt dieser Thread das Rendering des UI auf der mobilen Plattform und die mit dem UI verbundenen Interaktionen des Endbenutzers aus.
- JavaScript/JS-Thread: Übernimmt die Ausführung des in der App mit JavaScript programmierten React-Quellcodes über die JavaScript-Engine (JS-VM) – Hermes genannt. Dazu gehört das Laden der App, der Aufruf von in JavaScript programmierten Funktionen und die mit JavaScript realisierte Geschäftslogik.
- Layout/Shadow-Thread: Ist verantwortlich für das Layouting, das heißt den Aufbau des User-Interface. Dazu berechnet der Thread mithilfe der Layout-Engine Yoga (von Meta/
Facebook) die Positionen und die Größe der UI-Komponenten. Die so ermittelten UI-Daten bilden die Grundlage für die in React Native realisierte Rendering-Pipeline. - Bridge-Thread (Native Modules): Im Zentrum der React-Native-Architektur steht eine Bridge für die Kommunikation zwischen den Bestandteilen der Plattform. Um eine Unabhängigkeit aller beteiligten Seiten (JavaScript-, Layout/Shadow- und Main/Native-Thread) zu gewährleisten, kommt als Datenstruktur für die Bridge eine Queue (Warteschlange) zum Einsatz. Die Bridge bindet die nativen Funktionen der mobilen Plattform ein; dazu greift sie auf das Rendering für die Darstellung und das Event-Handling zwischen JavaScript und der nativen Plattform zurück.
Community strebt neue React-Native-Architektur an
Das Team bei Meta arbeitet mit der Community permanent an Verbesserungen für die Entwicklung mit React Native. So hat die eigene JavaScript-Engine Hermes die Start-up-Zeit verkleinert, die Dateigröße optimiert und die Performance der App verbessert.
Ökosystem für die Programmierung mit React Native bereitstellen
Analog zu React erfolgt die Programmierung mit React Native über TypeScript und JSX (siehe Teil 4 dieser Serie [4]), sodass dieselbe Infrastruktur als Ausgangsbasis für die Entwicklung dient. Deshalb kommt auf der Ebene des Betriebssystems (macOS, Windows) für die Ausführung von NPM-Packages als Laufzeitumgebung Node.js [5] und im Browser die JavaScript-Engine V8 von Google zum Einsatz.React Native setzt ein Node.js-System ab Version 18 voraus. Wie bei React empfiehlt es sich, für ein eventuelles Umschalten zwischen den benötigten Node-Versionen einen Node Version Manager zu installieren, zum Beispiel NVM [6] (vergleiche [4]) oder NVS (Node Version Switcher) [7]. Dieses Umschalten innerhalb der verschiedenen Projekte setzt eine Administrationsberechtigung voraus.Für Verwaltung und Management der Abhängigkeiten des geschriebenen Quellcodes stehen als Package/Projekt-Manager NPM oder Yarn zur Verfügung. Im Umfeld von React/React Native fällt die Wahl in der Regel auf Yarn – ein Gemeinschaftsprojekt von Meta/Facebook, Expo.dev [8], Google und Tilde. Eine Installation von Node.js enthält auch den NPM-Package-Manager und das Corepack-Tool; Yarn wird mit dem Terminalbefehl corepack enable projektbezogen installiert (siehe [4]).Soll eine React-Native-App lediglich für Android und/oder Windows entwickelt werden, so reicht das Betriebssystem Windows aus. Sobald allerdings als Zielplattform auch iOS und/oder macOS im Blickpunkt stehen, benötigt der Entwickler bei ausschließlichem Einsatz von React Native ein macOS-System.Die Entwicklung einer Android-App erfordert die Installation und Einrichtung von Android Studio für Programmierung und Test – entsprechend ist für iOS und/oder macOS die Xcode-IDE und als Package/Dependency-Manager CocoaPods (für Objective-C, Swift) notwendig. Android Studio benötigt ein Java Development Kit (JDK); für das aktuelle React Native soll unter macOS das Azul Zulu OpenJDK [9] in der Version 17 und unter Windows microsoft-openjdk17 [10] verwendet werden.Für das JDK muss die Umgebungsvariable JAVA_HOME eingerichtet werden. Da Android Studio für den Build Gradle nutzt, muss für das Projekt sichergestellt sein, dass Gradle das eingesetzte JDK referenziert.Zusätzlich benötigt Android Studio die Installation der Android SDK Platform Android 14 (UpsideDownCake) mit API-Level 34. Für das Android SDK muss die Umgebungsvariable ANDROID_HOME eingerichtet werden, abschließend sind noch die emulator- und platform-tools-Verzeichnisse von ANDROID_HOME in den Pfad aufzunehmen. Zudem gilt es aus den nachfolgenden SDK Tools von Android eine für die jeweilige Plattform passende Auswahl zu treffen: Intel x86 Emulator Accelerator (HAXM installer), Atom_64 System Image, Google APIs Intel x86 Atom System Image oder Google APIs ARM 64 v8a System Image (Apple M1 Silicon).Die Ausführung der mit React Native programmierten Android-App über Android Studio erfordert die Einrichtung eines passenden Android Virtual Device. Zudem benötigt Xcode die Xcode Command Line Tools, die Apple normalerweise zusammen mit Xcode ausliefert. Deren Installation zeigt Xcode über das Preference-Window im Bereich Locations an (Bild 2). Eine Aktualisierung der oben genannten Komponenten erfolgt im Bedarfsfall nachträglich für die Android-Studio-IDE über das Settings-Dialogfenster: Settings | Languages & Frameworks | Android SDK. Für die Xcode-IDE entfernt sudo rm -rf /Library/Developer/CommandLineTools die Command Line Tools, sodass der Terminalbefehl: xcode-select --install deren aktuelle Version installieren kann.
Xcode zeigt im Bereich Locations die zusammen mit der IDE installierte Version der Command Line Tools an (Bild 2)
Autor
Infrastruktur für das Testen der App auf mobilen Plattformen einrichten
Das Testen einer mit React Native für ein Mobilgerät entwickelten App erfolgt auf einer physischen Hardware, auf einem durch einen Emulator oder Simulator verfügbaren virtuellen Gerät oder über die mobile App Expo Go (basiert auf dem Expo-Framework für React Native). Während Android Studio das virtuelle Gerät über eine Emulator-Umgebung als Android Virtual Device (ADV) ausführt, bildet Xcode dieses über ein Modell anhand eines Simulators nach. Beide Realisierungen versetzen einen Programmierer in die Lage, die Android/iOS-App schnell zu testen, ohne diese vorher auf einem physischen Gerät installieren zu müssen. Zuvor richtet der Programmierer das für diesen Test zu simulierende/emulierende Mobilgerät über die Entwicklungsumgebung (Android Studio oder Xcode) ein.Nach dem Start von Android Studio befindet sich im Dialog Welcome to Android Studio in dessen Hamburger-Menü (drei Punkte) der Virtual Device Manager. Anschließend erscheint nach Klick auf das +-Icon-Symbol der Dialog Select Hardware mit allen verfügbaren Mobilgeräten. Das über die Spalte Play Store verfügbare Kontextmenü Clone legt eine Konfiguration für das konkrete Android Virtual Device (AVD) an. Anhand verschiedener vorzugebender Hardware-Eigenschaften wie Größe des Bildschirms, Kapazität des Hauptspeichers oder des Vorhandenseins spezieller Sensoren erfolgt die Einrichtung des AVD. Ein Klick auf die Schaltfläche Finish erzeugt einen Emulator nach abschließender Auswahl eines System Images und erneutem Klick auf eine Finish-Schaltfläche.Die Anlage eines für iOS zu simulierenden Mobilgeräts erfolgt in Xcode über das Fenster Devices and Simulators. Xcode zeigt dieses Fenster über die Menü-Kaskade Window | Devices and Simulators an. Die Schaltfläche Simulators listet alle derzeit verfügbaren und veränderbaren virtuellen Geräte auf. Einen neuen Simulator für ein bestimmtes Gerät erzeugt ein Klick auf das +-Icon-Symbol. Anschließend vergibt man einen Simulator Name, wählt in der Auswahlliste einen Device Type und über OS Version das gewünschte mobile Betriebssystem aus. Die Create-Schaltfläche legt abschließend den Simulator an und nimmt diesen in die Liste aller definierten Simulatoren auf.Beim Test der React-Native-App auf einer realen physischen Hardware dient die Android-Studio- oder Xcode-IDE als Vermittler. Im ersten Schritt aktiviert der Tester auf dem Mobilgerät den Entwicklermodus/Developer Mode. Nach dem Einrichten einer Verbindung vom PC zur mobilen Hardware und Auswahl des passenden Mobilgeräts in Android Studio überträgt die IDE die React-Native-App auf das Mobilgerät, wo diese zum Testen zur Verfügung steht. Ein in Xcode geöffnetes Devices and Simulators-Fenster lokalisiert nach Auswahl der Schaltfläche Devices und einem Klick auf das +-Icon-Symbol das verbundene Mobilgerät. Nach erfolgter Installation steht die React-Native-App zum Testen auf dem Apple-Mobilgerät bereit.Neues Projekt für Android und iOS mit demReact-Native-CLI anlegen
React Native unterstützt als UI-Bibliothek die Programmierung von Komponenten unabhängig von einem Framework. Für diese frameworkunabhängige Entwicklung stellt die Community das React-Native-CLI (Command Line Interface) zur Verfügung. So richtet der Terminalbefehl: npx @react-native-community/cli@latest init meinProjekt im neu angelegten Ordner meinProjekt ein Entwicklungsprojekt für die aktuelle React-Native-Version ein. Der Node Package Executor (NPX) steht über den NPM-Package-Manager nach einer Node-Installation zur Verfügung, da NPX zusammen mit NPM über Node ausgeliefert wird. Die Vorgaben der Antworten zu den Fragen des React-Native-CLI übernimmt der Programmierer anhand der Returntaste als Standardwerte.Der neu angelegte Ordner meinProjekt enthält neben den Projektdateien in den Unterverzeichnissen android und ios auch den Quellcode, der die React-Native-App in eine native Android- und iOS-App einbettet. Nach Abschluss des init-Befehls gibt dieser dem Entwickler einige Anleitungen aus, um die generierte App unter Android oder iOS auszuführen (Bild 3).
Nach der Neuanlage eines Entwicklungsprojekts gibt der init-Befehl des React-Native-CLI Anleitungen für nachfolgende Arbeitsschritte aus (Bild 3)
Autor
Um eine korrekte und vollständige Installation des React-Native-Ökosystems zu prüfen, steht der Terminalbefehl npx react-native doctor zur Verfügung. Nach dessen Ausführung im Projektverzeichnis erscheint eine Liste mit den korrekt installierten Bestandteilen (kleines hellgrünes Häkchen), Warnings (rundes grünes Punkt-Symbol) und Error-Meldungen (kleines rotes x-Symbol).Die ausgegebenen Meldungen weisen teilweise Untergruppen auf, was den aktuellen Stand der Installation einer Entwicklungsumgebung genauer ersichtlich macht. Anhand dieser Meldungen lassen sich die gegebenenfalls erforderlichen Nacharbeiten ableiten.Zur Programmierung von Quellcode eignen sich die beiden IDEs von Microsoft: VS Code oder Visual Studio. Unter macOS stellt Microsoft allerdings nur noch VS Code und nicht mehr die Visual-Studio-IDE bereit. Microsoft unterstützt Visual Studio nur noch für das eigene Betriebssystem Windows.In VS Code eignet sich die Extension React Native Tools aus dessen Marketplace für die Ausführung von React-Native-Kommandos und das Debugging der App. Nach einer Eingabe von React Native in der Command Palette von VS Code zeigt die IDE eine Liste aller verfügbaren Befehle an. Diese Liste umfasst einen recht umfangreichen Satz an Befehlen für das Management eines React-Native-Projekts. Zusätzlich enthält der Marketplace von VS Code noch weitere empfehlenswerte Extensions, beispielsweise ES7 React/Redux/React-Native/JS snippets für die schnellere Eingabe von Quellcode anhand von Code-Kürzeln.
Arbeiten mit der React-Native-App in einer Android-Umgebung
Im Umfeld einer Android-Entwicklungsumgebung stehen dem Programmierer verschiedene Terminalbefehle zur Verfügung:
Arbeiten mit der React-Native-App in einer iOS-Umgebung
Im Umfeld einer iOS-Entwicklungsumgebung stehen dem Programmierer ebenfalls verschiedene Terminalbefehle zur Verfügung:
React-Native-Projekt für JavaScript mit demExpo-Framework anlegen
Neben dem frameworkunabhängigen React-Native-CLI gibt es weitere Frameworks wie Expo oder Ignite, um React-Native-Apps vorkonfiguriert für eine einfachere, produktivere Entwicklung zu erzeugen. Für diesen Zweck stellt Expo ein eigenes CLI sowie die Expo Application Services (EAS) zur Verfügung.Während das CLI ein neues Entwicklungsprojekt abgestimmt auf den Einsatz in der Expo-Welt erstellt, stehen im Zentrum von EAS die Core Services: Build, Submit und Update. Der über das Internet verfügbare Build-Service hilft bei der Bereitstellung und Verteilung von Apps. Dabei übernimmt Submit insbesondere die Übertragung der App in die App-Stores. Der Update-Service unterstützt die Verteilung von Projekt-Updates wie Bug-Fixes; dies setzt allerdings die Integration der Bibliothek expo-updates in der React-Native-App voraus.Ein neues Entwicklungsprojekt im Ordner neuApp legt der Expo-CLI-Befehl npx create-expo-app@latest neuApp an. In Anlehnung an das React-Native-CLI erzeugt Expo einen neuen Projektordner und gibt nach Abschluss eine Anleitung für die empfohlene weitere Arbeitsweise aus. Der von Expo generierte Quellcode basiert auf reinem TypeScript; neben Android und iOS unterstützt Expo für die React-Native-App auch das Web. Allerdings zielt Expo nicht auf den direkten Einsatz von nativen Modulen mit Java/Kotlin oder Objective-C/Swift ab. Vielmehr greift der Programmierer für diesen Zweck auf den Custom-Code der Expo-Module zurück. Der Befehl npm run android führt die generierte React-Native-App direkt auf einem Virtual Device (Bild 4) aus; dies setzt einen Start des AVD über die Android-Studio-IDE voraus. Alternativ startet der Befehl npm run ios oder npm run web die App auf iOS oder in einem Webbrowser.
Das vom Expo-Framework generierte React-Native-Projekt führt über den Befehl „npm run android“ die App direkt auf einem Virtual Device aus (Bild 4)
Autor
Expo besitzt ein eigenständiges CLI, dessen Befehle in einem React-Native-Projekt über npx epo zur Verfügung stehen. So gibt der Terminalbefehl npx expo --version die Versionsnummer des im Projekt installierten Expo-Systems aus. Unabhängig von der Laufzeitplattform startet in einem Projektordner der Terminalbefehl npx expo start den Expo-Entwicklungsserver und stellt die React-Native-App über den Metro-Bundler zur Ausführung bereit. Dabei gibt Expo einen QR-Code (Quick Response) aus, um die App auf einem Smartphone über die Expo-Go-App auszuführen: Ein Scan des QR-Codes über die Expo-Go-App (Android) oder die Camera-App (iOS) startet die React-Native-App und zeigt diese in Expo Go an. Für eine React-Native-App stehen über Expo Go alle Komponenten und APIs des Expo-Frameworks zur Verfügung.Abschließend zeigt der Expo-Entwicklungsserver eine Liste zusätzlich verfügbarer Tastaturbefehle an. Die Eingabe des Fragezeichens (?) auf der Tastatur gibt die Liste, ergänzt um weitere Befehle, erneut aus. Beispielsweise ermöglicht [Umschalt]+[A] über die Cursor-Steuerung eine Auswahl der in Android Studio angelegten Virtual Devices. Dazu öffnet der Expo-Entwicklungsserver das Virtual Device, nimmt ein Bundling auf diesem vor und zeigt die React-Native-App an. Zusätzliche Entwicklungswerkzeuge macht die Tastenkombination [Umschalt]+[M] verfügbar, um zum Beispiel Debugging über die App oder die React devtools im Browser durchzuführen. Die Tastenkombination [Strg]+[D] beendet den Entwicklungsserver. Das Management des Expo-Entwicklungsservers basiert auf den beiden Dateien devices.json (im .expo-Ordner) und package.json.
Expo-App für native Programmierung erweitern
Primär ist die von Expo generierte React-Native-App auf die Programmierung mit TypeScript und dem Expo-Framework ausgerichtet. Das CLI-Kommando <span class="CharOverride-1">npx expo prebuild</span> von Expo erzeugt im Projektordner die beiden Unterverzeichnisse <span class="CharOverride-1">android</span> und <span class="CharOverride-1">ios</span> mit dem benötigten nativen Quellcode.
Struktureller Aufbau eines React-Native-Entwicklungsprojekts
Das React-Native-CLI und Expo strukturieren ein React-Native-Projekt in verschiedene Unterverzeichnisse mit mehreren Dateien. Als zentrale Dateien sind für das React-Native-CLI die App.tsx und für Expo die index.tsx im app\(tabs)-Ordner, die app.json-, die README.md- und die package.json-Datei zu nennen. Bei der App.tsx- beziehungsweise der index.tsx-Datei handelt es sich um den Einstiegspunkt der React-Native-App. Diese Datei dient beim Starten der App dem Rendering als Wurzel/Start-Komponente. Die app.json-Datei enthält die wichtigsten Informationen zur Konfiguration des React-Native/Expo-Projekts. Darin befinden sich der Name der App, die anzuzeigenden Icons, der Aufbau des Start-Bildschirms, die verwendeten Plug-ins des Expo-Frameworks und ähnliche Informationen.Über die README.md-Datei erhält der Entwickler wichtige Ratschläge zum Arbeiten mit dem Projekt. Das React-Native/Expo-CLI erzeugt die metro.config.js-Datei mit Anweisungen für das Bundling über Metro, während das Expo-CLI das komplette Bundling über ein eigenes Unterverzeichnis node_modules\expo abwickelt. Wie in jedem TypeScript-Projekt dokumentiert die package.json-Datei die verschiedenen Abhängigkeiten des Projekts und listet die verfügbaren Skripts auf.Zu den wichtigsten Unterverzeichnissen eines React-Native-Projekts gehören die Folgenden (im Bedarfsfall legt der Entwickler diese manuell an):- androids und ios: Diese beiden Ordner im Projektverzeichnis erzeugt nur das React-Native-CLI; in einem mit Expo generierten Projekt sind diese als Unterverzeichnis im Ordner node_modules\expo erst nach dem Start einer Android/iOS-App vorhanden. Beide Ordner nehmen die von der React-Native-App benötigten Dateien für Build-Management und Ausführung der App auf.
- app: Dieser Ordner (der nur vom Expo-Framework automatisch erzeugt wird) enthält in verschiedenen Dateien den generierten TypeScript/JSX Source-Code rund um die index.tsx-Datei der React-Native-App.
- assets: Dieser Ordner (nur vom Expo-Framework automatisch erzeugt) nimmt alle für das Projekt benötigten Ressourcen wie Schriftarten, Images und Ähnliches auf.
- api: In diesem vom Programmierer anzulegenden Unterverzeichnis befindet sich der Quellcode, um Daten zu lesen oder API-Calls auszuführen.
- components: Alle wiederverwendbaren Komponenten des UI befinden sich in diesem Verzeichnis. Die für die Navigation (Routing) relevanten Komponenten legt der Entwickler im Unterverzeichnis navigation ab. Beide Ordner und die dort als TypeScript/JSX-Dateien generierten Komponenten erzeugt nur das Expo-Framework automatisch.
- constants: Ressourcen für das Theming der App wie Farben und Ähnliches enthält dieses Unterverzeichnis, das nur Expo automatisch anlegt.
- hooks: Vom Entwickler anzulegendes oder vom Expo-Framework generiertes Verzeichnis, das der Ablage von React Functional Components dient.
- macos und windows: Diese beiden Ordner enthalten die nachträglich zu installierenden NPM-Packages von Microsoft für die React-Native-Entwicklung unter macOS beziehungsweise Windows. Im jeweiligen Ordner befinden sich die erforderlichen Dateien für eine Programmierung mit React Native unter macOS beziehungsweise Windows.
- node_modules: Dieser vom npm install- oder yarn-Befehl erzeugte Ordner nimmt alle für das Projekt erforderlichen NPM-Packages auf. Eventuelle zusätzliche Packages für die Entwicklung mit React Native installiert der NPM-Package-Manager ebenfalls in dieses Verzeichnis.
- scripts: Enthält das Expo-Script reset-project.js, um den vom Expo-Framework erzeugten Quellcode in ein eigenes Unterverzeichnis app-example zu verschieben und anschließend eine neue leere React-Native-App für die Programmierung mit Expo zu erzeugen.
- styles: Dieser vom Entwickler anzulegende Ordner hilft beim Aufbau eines zentralisierten Stylings; hier legt der Programmierer globale Stylesheets oder spezielle Styles für bestimmte Komponenten ab.
Bereitgestellte Core Components in App und Expo Snack verwenden
React Native besitzt eine Vielzahl von Core Components, die ein Programmierer direkt in einer App einsetzen kann. Im Bereich Development | Components der React-Native-Homepage findet ein Entwickler den Menüeintrag Core Components and APIs eingeteilt in verschiedene Gruppen: Basic Components, User Interface, List Views, Android/iOS-specific und Others. Zu den Basic Components zählen die View-, Text-, Image-, TextInput-, ScrollView und StyleSheet-Komponenten. Bei den speziell auf Android oder iOS ausgerichteten Core-Komponenten handelt es sich im Wesentlichen um Wrapper der jeweiligen Android- oder UIKit-Klassen.Generell erfolgt die Programmierung mit einer Core Component wie in React üblich mittels JSX und JavaScript/TypeScript. Der Entwickler codiert im Quellcode eine eigene Komponente, nutzt dabei Core Components und liefert über eine export-Anweisung die selbst programmierte Komponente zurück. In Anlehnung an Online-IDEs beziehungsweise Communities wie CodePen oder JSFiddle hat Expo das Online-Tool Expo Snack [11] realisiert. Dessen Website erleichtert dem Entwickler wesentlich das Prototyping und Testen einer neuen Komponente. Nach Eingabe des Quellcodes und Auswahl einer Ausgabeoption bereitet Expo Snack die Komponente für das jeweilige Endgerät vor. Dies kann auf einem eigenen Mobilgerät, durch Emulation einer Android-, iOS-App oder im Browser als Web-App erfolgen (Bild 5).
Expo Snack zeigt eine programmierte React-Native-Komponente unmittelbar auf einem Mobilgerät an (Bild 5)
Autor
Besitzt der Entwickler einen eigenen Expo-Account, so bietet dieser im Bereich Snacks die Schaltfläche + New Snack an. Ein Klick darauf erzeugt auf der Website von Expo Snack eine neue React-Native-App, stellt deren Projektstruktur bereit und öffnet die App.js-Quelldatei. Anhand der Online-Features von Expo Snack legt der Entwickler neue Ordner oder eigene Source-Dateien an. Im eigenen Expo-Account speichert der Programmierer eigene Projekte ab und macht diese so späteren Expo-Sessions wieder zugänglich. Zusätzlich zu den Core Components existieren viele weitere React-Native-Libraries, die ebenfalls fertig programmierte Komponenten bereitstellen. Für eine gezielte Suche nach solchen Komponenten steht eine Website, das sogenannte React Native Directory [12] der React-Native-Community, zur Verfügung.Snacks
Beispiele für den Einsatz von Fluent-UI-Komponenten
Die von Microsoft bereitgestellte FluentUI-Tester-App enthält Beispiele für die Programmierung mit den Fluent-UI-Komponenten. Die FluentUI-Tester-App ist Bestandteil des GitHub-Repositorys Fluent UI React Native [19]. Der <span class="CharOverride-1">app-</span>Ordner enthält die FluentUI-Tester-App im Verzeichnis <span class="CharOverride-1">fluent-tester</span>. Die vorhandenen Anleitungen geben Hilfestellungen, um die FluentUI-Tester-App auf einer bestimmten Plattform auszuführen.
Styling von React-Native-Komponenten in einer Anwendung
React Native unterstützt verschiedene Möglichkeiten, eine Komponente des User-Interface (UI) mit einem Style zu versehen. Als gängige Methoden bieten sich das Style Prop der jeweiligen Komponente, die Verwendung eines StyleSheets oder der Einsatz der styled-components-Library [13] an. Dabei lehnen sich alle drei genannten Methoden an das bekannte CSS-Styling an.Das Styling über ein Style Prop eignet sich direkt für eine Core Component, wenn diese ein Prop mit dem Namen style besitzt. Die Bezeichnungen und die Werte eines Styles stimmen in der Regel mit denjenigen des CSS überein. Allerdings erfolgt die Schreibweise der Bezeichnungen in CSS gemäß Camel Casing – also beispielsweise fontFamily anstatt font-family.Um durch das Styling über das Style Prop die Komplexität einer Komponente nicht übermäßig zu erhöhen, bietet es sich an, das Styling an einer zentralen Stelle im Quellcode der React-Native-Komponente zu definieren. Dazu kommen das API der StyleSheets-Komponente aus den Core Components sowie die Anlage eines styles-Objekts zum Einsatz. Über dieses styles-Objekt reicht der Programmierer das definierte Styling an ein Style Prop der React-Native-Komponente weiter (Listing 1).Listing 1: Styling einer React-Native-Komponente
import { View, StyleSheet } from 'react-native';<br/>{/* Der View-Komponente ihre Styles zuordnen */}<br/>&lt;View style={styles.container}&gt;<br/> ...<br/>&lt;/View&gt;<br/>{/* Das StyleSheet anlegen und die Styles <br/> deklarieren */}<br/>const styles = StyleSheet.create({<br/> container: {<br/> flex: 1,<br/> padding: 24,<br/> backgroundColor: 'blue',<br/> ...<br/> },<br/>});
Für ein übergebenes Objekt legt StyleSheets dessen CSS-Properties fest, zum Beispiel backgroundColor, bottom, color, fontSize, height und weitere. Das Styling erfolgt über das JavaScript-Objekt styles für alle React-Native-Komponenten an einer zentralen Stelle. Der Programmierer greift bei der Deklaration der React-Native-Komponente auf den jeweils gewünschten Style zurück. Diese Wiederverwendung stellt einheitliche Styles in der App sicher.Alternativ bietet sich der Einsatz der styled-components-Library an; diese verwendet das normale CSS-Styling. Um diese Bibliothek in einem React-Native-Projekt zu verwenden, reicht eine einfache Installation über npm install styled-components aus.Das Styling mittels der styled-components-Library basiert auf sogenannten Tagged-Template-Literals. Mit diesen erfolgt das Styling nach der import styled from ’styled-components’-Anweisung direkt bei der React-Native-Komponente, die ihre Styles anhand der Backtick-Syntax erhält. Jedes Vorlagenliteral beginnt mit einem Backtick-Symbol ` (auch Grave Accent genannt), darauf folgen die Deklarationen der gewünschten CSS-Stile, und am Schluss steht wieder ein Grave Accent. Diese Vorgehensweise verknüpft die React-Native-Komponente über das Tagged-Template-Literal mit den CSS-Styles der styled-components-Library.
Routing und Navigation in einer React-Native-Anwendung deklarieren
Jede App benötigt für Routing und Navigation eine individuelle Lösung, da React Native diese Aufgaben selbst nicht abdeckt. Beim Einsatz von Expo empfiehlt es sich, das in Expo integrierte dateibasierte Routing zu verwenden. Der Expo Router unterstützt alle gängigen Plattformen (Android, iOS und Web). Für die Navigation mit dem Expo Router muss in der package.json-Datei im main-Bereich der Eintrag ”expo-router/entry” stehen. Zudem muss im Bereich plugins in der app.json-Datei der ”expo-router“ aufgeführt sein. Die genannten Voraussetzungen richtet der Terminalbefehl npx create-expo-app@latest automatisch ein. Zur Navigation eignet sich die Link-Komponente des Expo Routers.Eine Alternative für Routing/Navigation stellt die Library React Navigation dar. Der Terminalbefehl npm install @react-navigation/native @react-navigation/native-stack installiert diese Routing/Navigation-Bibliothek. Zusätzlich benötigt die React-Navigation-Library noch die NPM-Packages react-native-screens und react-native-safe-area-context. Dabei muss der Programmierer die komplette React-Native-App in einen NavigationContainer einbetten (Listing 2). Die Steuerung der Navigation erfolgt über eine Stack.Navigator-Komponente. Dazu deklariert der Entwickler die jeweils anzuzeigende React-Native-Komponente über eine Stack.Screen-Komponente.Listing 2: NavigationContainer und Stack verwenden
// App.tsx in einen NavigationContainer einbetten<br/>import * as React from 'react';<br/>import { View, Text } from 'react-native';<br/>import { NavigationContainer } from <br/> '@react-navigation/native';<br/>import { createNativeStackNavigator } from <br/> '@react-navigation/native-stack';<br/>// Alle vorhandenen Bildschirme/Screens der App <br/>// importieren<br/>import HomeScreen from './HomeScreen';<br/>...<br/>// Über eine &lt;Stack.Navigator&gt;-Komponente die <br/>// verschiedenen Ausgaben der Bildschirme<br/>// der React-Native-App verfügbar machen<br/>const Stack = createNativeStackNavigator();<br/>function App() {<br/> return (<br/> &lt;NavigationContainer&gt;<br/> &lt;Stack.Navigator&gt;<br/> &lt;Stack.Screen name="Home" <br/> component={HomeScreen} /&gt;<br/> ...<br/> &lt;/Stack.Navigator&gt;<br/> &lt;/NavigationContainer&gt;<br/> );<br/>}<br/>export default App;
Die eigentliche Navigation von einem Bildschirm zu einem anderen erledigt das bei jeder UI-Komponente über die React-Navigation-Library vorhandene Navigation Prop. Soll zum Beispiel vom Home-Bildschirm ausgehend durch Anklicken einer Schaltfläche auf einen Details-Bildschirm (Details.tsx) verzweigt werden, so erreicht dies beim onPress-Event die folgende Anweisung:
<Button
title="Details-Bildschirm anzeigen"
onPress={() => navigation.navigate('Details')}
/>
Details ist als Stack.Screen in der Stack.Navigator-Komponente definiert. Das Navigation Prop unterstützt auch die Übergabe von Parametern an eine sich öffnende UI-Komponente. Diese erhält über das Route Prop anhand der Anweisung route.params Zugriff auf übergebene Parameter. Anschließend verarbeitet die UI-Komponente die so erhaltenen Parameter.Die React-Navigation-Library kennt beim Mobilgerät auch eine Steuerung anhand der Zurück/Back-Geste. Im Quellcode ermöglicht die Anweisung navigation.goBack() eine Verzweigung zum vorherigen Bildschirm. Das goBack-Statement eignet sich auch für eine Verknüpfung mit einer Zurück/Back-Schaltfläche.
+[M] unter macOS beziehungsweise [Ctrl]+[M] unter Windows) zum Einsatz kommen; alternativ ist im Terminalfenster adb shell input keyevent 82 einzugeben. Danach wird im In-App Developer Menu der Eintrag Open Debugger angeklickt und in Chrome die Adressleiste chrome://inspect geöffnet. Jetzt folgt ein Klick auf die Schaltfläche Configure … neben der Checkbox Discover network targets(Bild 6). Abschließend ist als Target der localhost mit der Port-Adresse des Metro-Entwicklungsservers einzugeben. Ein Klick auf den inspect-Verweis unterhalb von Hermes React Native öffnet die Chrome DevTools.
Alternativen für das Debugging einer React-Native-Anwendung
Debugging zielt darauf ab, Fehler in der App schnellstmöglich zu finden und zu beseitigen. Wie bei jeder in TypeScript implementierten App bieten sich drei Techniken für das Debugging an: Logging, Debugging über die Chrome DevTools oder Debugging in VS Code.Für das Logging kommen das JavaScript-Objekt console und die mit ihm verfügbaren Methoden zum Einsatz. Die zugehörigen Methoden log, info, debug, warn und error schreiben die übergebenen Parameter als Ausgabe in das Terminalfenster, in dem Metro [14] den Entwicklungsserver für die React-Native-App ausführt.Die warn()- und error()-Methoden erzeugen neben einer Ausgabe im Terminalfenster auch eine Informationsmeldung auf dem verknüpften Mobilgerät. Zusätzlich zeigen beide Methoden im Terminalfenster noch einen Stacktrace aller bisher seitens der App ausgeführten JavaScript-Methoden an. Die assert()-Methode des console-Objekts gibt den übergebenen Parameter nur aus, wenn der erste Parameter auf false steht. Deshalb eignet sich der boolesche Parameter von assert als Schalter zur Aktivierung des Loggings. Die beiden Methoden time() und timeEnd() von console helfen beim Monitoring und ermitteln die Ausführungszeit.Um die App über die Chrome DevTools zu debuggen, startet man die React-Native-App und aktiviert das In-App Developer Menu wie folgt: im iOS-Simulator mit der Tastenkombination [Cmd]+[D] oder alternativ per Device | Shake), während im Android-Emulator die Tastenkombinationen [Cmd]+[M] unter macOS beziehungsweise [Ctrl]+[M] unter Windows) zum Einsatz kommen; alternativ ist im Terminalfenster adb shell input keyevent 82 einzugeben. Danach wird im In-App Developer Menu der Eintrag Open Debugger angeklickt und in Chrome die Adressleiste chrome://inspect geöffnet. Jetzt folgt ein Klick auf die Schaltfläche Configure … neben der Checkbox Discover network targets(Bild 6). Abschließend ist als Target der localhost mit der Port-Adresse des Metro-Entwicklungsservers einzugeben. Ein Klick auf den inspect-Verweis unterhalb von Hermes React Native öffnet die Chrome DevTools.

Das In-App Developer Menu auf dem Mobilgerät unterstützt für React Native ein Remote-Debugging in der eigenen JavaScript-Engine (Hermes) (Bild 6)
Autor
VS Code unterstützt über die Extension React Native Tools aus dem Marketplace das Debugging innerhalb der IDE. Nach deren Installation erscheint bei einem Klick auf Run and Debug in der linken Menüleiste der IDE der Eintrag To customize Run and Debugcreate a launch.json file. Ein Klick auf diesen Verweis und Auswahl von React Native in der select debugger-Liste zusammen mit der gewünschten Debug-Option (Android, iOS, Windows oder macOS) legt eine launch.json-Datei im .vscode-Ordner an. Nach der Definition verschiedener Breakpoints im Quellcode der React-Native-App startet die Funktionstaste [F5] oder das Menü Run | StartDebugging das Debugging innerhalb der VS-Code-IDE.
React-Native-Framework für macOS und Windows mit Fluent UI einsetzen
Aufgrund der zunehmenden Verbreitung von React Native entschloss sich Microsoft, die Cross-Plattform-Unterstützung des Frameworks um macOS und Windows zu erweitern. Aufbauend auf dem React-Native-Layer stellen verschiedene NPM-Packages zusätzliche UI-Komponenten für macOS [15] (ab 10.13) und Windows [16] (ab Version 10) bereit. Den zugehörigen Quellcode macht Microsoft über zwei GitHub-Repositories mit ausführlicher Dokumentation zugänglich. Dabei können Entwicklung und Test einer macOS- oder Windows-App stets nur auf dem jeweiligen Betriebssystem erfolgen. Den Aufbau eines macOS- oder Windows-Projekts beschreibt die Dokumentation von Microsoft anhand schrittweiser Anleitungen.Alternativ erhält man ein Starter-Projekt über den von Microsoft bereitgestellten Builder der React-Native-Test-App [17]. So startet der Terminalbefehl npx --package react-native-test-app@latest init die Kommandozeile des Builders. Nach Eingabe eines Namens für die neue App bietet der Builder von Microsoft für die React-Native-Test-App alle derzeit für ein React-Native-Projekt verfügbaren Entwicklungsplattformen an. Nach einer Auswahl über die Return-Taste und Angabe eines Projektordners erzeugt dieser Builder für alle ausgewählten Zielplattformen den passenden Quellcode. Abschließend installiert im neuen Projektordner der Aufruf von npm install oder yarn alle für die jeweilige Plattform erforderlichen NPM-Packages.Die nachfolgenden Build-Befehle yarn build:macos beziehungsweise yarn build:windows erzeugen im macos- beziehungsweise windows-Ordner die erforderlichen Konfigurationsdateien für das Building der App. Alle dazu benötigten Entwicklungsdateien für React Native legt Yarn zusammen mit dem Metro-Bundler an.Die anschließende Weiterarbeit setzt ein macOS- oder ein Windows-Betriebssystem voraus: Für macOS generiert der Terminalbefehl pod install --project-directory=macos beziehungsweise für Windows npx install-windows-test-app --use-nuget die benötigten Konfigurationsdateien für den jeweiligen Betriebssystem-Build. Dabei muss in Windows der Entwicklermodus/Developer Mode für die Ausführung einer React-Native-App aktiviert sein.Die macOS- beziehungsweise Windows-App startet der Terminalbefehl yarn macos(Bild 7) beziehungsweise yarn windows. Der Einsatz von Fluent UI in der generierten React-Native-App erfordert eine Installation des zugehörigen NPM-Packages @fluentui/react-native. Danach stehen alle Fluent-UI-Komponenten für die React-Native-App über eine Import-Anweisung (import { FluentKomp } from ’@fluentui/react-native/FluentKomp’;) als JSX-Tag wie folgt zur Verfügung: <FluentKomp label=”Das ist eine Fluent UI-Komponente” />. Nähere Informationen zum Einsatz auf den einzelnen Plattformen liefert die SPEC.md-Datei im GitHub-Repository von Fluent UI React Native. Diese Datei befindet sich dort im Ordner packages/components bei der jeweiligen Komponente.
Das Starter-Projekt für macOS enthält den Quellcode für die übliche Welcome-to-React-Native-App (Bild 7)
Autor

Nach Auswahl einer Fluent UI-Komponente zeigt ein Klick auf den rechts oben im Fenster stehenden roten SPEC-Verweis beispielhaften Quellcode an (Bild 8)
Autor
Per Cross-Plattform-Strategie die Portabilität für die Zukunft sichern
Die heutige Anwendungslandschaft ist gekennzeichnet von einer Dreiteilung in Desktop, Web und mobile Welt. Insofern eignet sich eine Anwendungsentwicklung auf Cross-Plattform-Basis besonders gut als strategische Ausrichtung, um alle drei Welten abzudecken. Insbesondere gilt das, seit Microsoft für das React-Native-Framework die beiden Betriebssysteme macOS und Windows auf dem Desktop erschlossen hat. Damit unterstützt React Native eine durchgängige Cross-Plattform-Entwicklung, die Produktivität und Effizienz ins Zentrum rückt.Der hohe Grad an Wiederverwendung und die effiziente Arbeitsweise von React Native bietet einer Entwicklungsorganisation das nötige Potenzial, um mit ihren Apps in der Zukunft auf Erfolgskurs zu bleiben. Die Vergangenheit hat gezeigt, dass die kontinuierlich wachsende React- und React-Native-Community für neu aufkommende Technologien geeignete Lösungswege erschließt. Somit gewährleistet React Native für eigene Apps zukünftig einen stabilen, erfolgreichen Entwicklungspfad. Basiert die Anwendung zusätzlich noch auf dem Design-System Fluent, so integriert die App für ihre Benutzer die mit Fluent verbundene User Experience.Fussnoten
- [1] Homepage von React Native, https://reactnative.dev
- [2] Homepage des Design-Systems Fluent 2, https://fluent2.microsoft.design/
- [3] Homepage von React, https://react.dev
- [4] Frank Simon, Web-Apps mit Fluent UI Web, dotnetpro 8/2024, Seite 48 ff., http://www.dotnetpro.de/A2408FluentUI
- [5] Homepage von Node.js, https://nodejs.org
- [6] GitHub-Repository Node Version Manager (NVM), https://github.com/nvm-sh/nvm
- [7] GitHub-Repository von Node Version Switcher (NVS), https://github.com/jasongin/nvs
- [8] Homepage von Expo, https://expo.dev
- [9] Download Azul Zulu OpenJDK Version 17 für macOS, http://www.dotnetpro.de/SL2410FluentUI1
- Download Microsoft OpenJDK Version 17 für Windows, http://www.dotnetpro.de/SL2410FluentUI2
- Homepage von Expo Snack, https://snack.expo.dev/
- Homepage des React Native Directorys, https://reactnative.directory
- Homepage der styled-components-Library, https://styled-components.com
- Metro – The JavaScript bundler for React Native, https://metrobundler.dev
- GitHub-Repository von React Native für macOS, http://www.dotnetpro.de/SL2410FluentUI3
- GitHub-Repository von React Native für Windows, http://www.dotnetpro.de/SL2410FluentUI4
- GitHub-Repository der React Native Test App, http://www.dotnetpro.de/SL2410FluentUI5
- GitHub-Repository der Config-Plug-ins von Expo, http://www.dotnetpro.de/SL2410FluentUI6
- GitHub-Repository von Fluent UI React Native, http://www.dotnetpro.de/SL2410FluentUI7