Multiplattform-Frameworks Artikel 1 von 5: React Native
React Native
In diesem Artikel zum Beginn eine einfache Einführung in das Framework React Native gegeben. Im Anschluss wird die Erstellung einer exemplarischen Applikation sowie das Builden dieser für Android beschrieben. Darauf folgt eine Beschreibung, wie mit dem Framework ebenfalls Windows und Mac bedient werden kann. Zum Schluss wird auf Vorteile und Limitierungen eingegangen.
Dieser Artikel ist Teil einer Reihe von Artikeln, in welchen verschiedene Frameworks für die Multiplattform-Entwicklung vorgestellt werden. Die anderen Beiträge können unter den folgenden Links eingesehen werden:
- Multiplattform-Frameworks Artikel 2 von 5: Flutter
- Multiplattform-Frameworks Artikel 3 von 5: Ionic
- Multiplatform-Frameworks Artikel 4 von 5: .NET MAUI
- Multiplattform-Frameworks Artikel 5 von 5: Quasar
- Multiplattform-Frameworks: Fazit
Was ist React Native
Bei React Native handelt es sich um ein Framework, welches es erlaubt, mit dem Schreiben einer Codebasis gleichzeitig mehrere Plattformen zu bedienen. Dabei wird das Interface mit React gebaut und kann als native Android oder IOS App gebuilded werden (React Native, 2021a). Damit dies möglich ist, werden vom Framework plattformagnostische Bausteine angeboten, welche auf das entsprechende Gegenstück der Zielplattform abgebildet werden. Beispielsweise kann statt einem HTML Input-Tag ein TextInput-Baustein verwendet werden (React Native, 2021b). Das Framework wird dabei unter einer MIT-Lizenz angeboten, welche die freie Verwendung ermöglicht (Github, 2021a).
Anforderungen
Damit React Native verwendet werden kann, wird NodeJs 12+ (NodeJs, 2021) und NPM (NPM, 2021) benötigt. Durch eine Installation von NodeJs wird ebenfalls NPM installiert. Zudem wird für das Builden einer Android-Anwendung das Android SDK benötigt, welches zum Beispiel automatisch bei der Installation von Android Studio (Android Studio, 2021) mit installiert wird. Ebenfalls wird Java 15 für das Builden einer Android-Version benötigt (Java, 2021). Zudem werden Visual Studio und Visual Studio Code vorausgesetzt (Microsoft, 2021a). Da in diesem Artikel Expo (Github, 2021b) verwendet wird, wird für die Entwicklung auf dem Smartphone aus dem jeweiligen App-Store die Expo App installiert.
Initialisieren des Prototypens
In diesem Abschnitt wird der Prozess der Initialisierung einer exemplarischen Anwendung unter der Verwendung von Expo beschrieben. Expo ist eine Opensource Plattform, die das schnelle und einfache Erstellen von React Native Anwendungen ermöglicht (Github, 2021b) . Expo wird hier verwendet, um ohne viel Aufwand zu einem Ergebnis zu kommen. Wenn jedoch kein Drittanbieter verwendet werden soll, dann kann ein Projekt über die React Native CLI erstellt werden.
Um ein Projekt mittels Expo zu erstellen und zu starten, werden die folgenden Befehle ausgeführt:
# installation von Expo $ npm i -g expo-cli # Erstellung eines Projekts über die Expo Cli $ expo init HelloWorld # Starten der Anwendung $ cd HelloWorld $ npm start
Abbildung 1: Befehle zum initialisieren eines Expo-Projektes.
Zu beachten ist, dass in diesem Prototypen Typescript (Typescript, 2021) verwendet wurde. Ein Typescript-Template kann beim Initialisieren des Projekts ausgewählt werden. Wenn die Anwendung für die Entwicklung gestartet wurde, wird der folgende Bildschirm gezeigt:
Abbildung 2: Startbildschirm mit Expo.
Unten links im Bildschirm sind verschiedene Möglichkeiten für die Entwicklung gegeben: Durch das Einscannen des QR-Codes kann sich mit einem Smartphone für die Entwicklung verbunden werden. Alternativ kann die App im Browser oder einem Emulator für IOS oder Android gestartet werden. Wenn ein iPhone verwendet wurde, sieht das Ergebnis wie folgt aus:
Abbildung 3: Der Prototyp auf dem iPhone mit den DevTools geöffnet.
In diesem Bild wird zusätzlich am unteren Bildschirm ein Objekt-Inspector angezeigt. Dieser und andere DevTools können geöffnet werden, wenn das iPhone geschüttelt und aus dem geöffneten Menü das gewünschte Tool ausgewählt wird.
Für den weiteren Verlauf ist zu beachten, dass für die Erstellung des Prototypen der Weg über Expo verwendet wurde. Für das Builden wurde jedoch die React Native CLI verwendet, damit man nicht abhängig von einem Drittanbieter ist. Das Builden über Expo nimmt viel Zeit in Anspruch, da man seine Dateien zu Expo hochlädt und dann dort in eine Warteschlange für Builds eingereiht wird. Somit wurde Expo nur für schnelle Resultate und die React Native CLI für das Builden verwendet. Zu Beachten ist, dass für das Builden das der exakt selbe Prototyp verwendet wurde.
Entwicklung der Prototypens
Jetzt geht es an die Entwicklung des Prototypen. Dabei ist zu beachten, dass der Prototyp nur dazu dient, sich die Konzepte von React Native vor Augen zu führen. Der Prototyp soll aus drei Ansichten bestehen: Einer Index-Seite einer Seite, die eine Liste von Nutzern enthält, und eine Ansicht, die als Hilfe dienen soll.
Erstellung der Nutzerliste
Das Ziel dieser Ansicht ist es, sich an die Konzepte von React Native zu gewöhnen. Dafür soll diese Ansicht einen Text-Input und eine Liste von Nutzern beinhalten. Durch eine Eingabe in den Text-Input soll ein Nutzer der Liste hinzugefügt werden. Nutzer werden dabei nur mit einem Namen repräsentiert. Die verwendeten User bestehen aus einer Id und einem Namen. Der Aufbau wird in der folgenden Abbildung vorgestellt:
import React, { useState } from "react"; import { StyleSheet, View } from "react-native"; import UserForm from "../components/user-form/user-form"; import UserList from "../components/user-list/user-list"; import IUser from "../model/user.model"; export default function UserScreen(): React.ReactElement { const [users, setUsers] = useState<IUser[]>([ { id: 1, name: "Jürgen" }, { id: 2, name: "Hans" }, { id: 3, name: "Peter" }, ]); function addUser(user: IUser) { setUsers([...users, user]); } return ( <View style={Styles.container}> <UserForm addUser={addUser}></UserForm> <UserList users={users}></UserList> </View> ); }
Abbildung 4: Komponente UserScreen.
Die Komponente verwaltet eine Liste von Nutzern und besitzt eine Funktion, um Nutzer hinzuzufügen. Zurückgegeben wird bekanntes JSX mit zwei Komponenten, die später vorgestellt werden. Bei genauerer Betrachtung fällt auf, dass der Wrapper eine View-Komponente ist. Bei dieser Komponente handelt es sich um eine zuvor erwähnte plattformagnostische Komponente, die von React Native angeboten wird. Für das Styling der Komponente, wird ein Stylescheet über Javascript definiert. Es werden keine CSS-Dateien verwendet. Die folgende Abbildung zeigt das für diese Komponente definierte CSS:
const Styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", alignItems: "center", justifyContent: "center", padding: 20, }, });
Abbildung 5: Styles im UserScreen.
Es fallen die folgenden Dinge bei diesem CSS auf: Es werden die Eigenschaften eines Flex-Containers verwendet und beim Padding fehlt die Einheit. Die Flex-Eigenschaften können verwendet werden, da der View-Baustein von React-Native per Default Flexbox unterstützt. Beim Padding fehlt die Einheit, da die Einheit plattformagnostisch sein soll. Jedoch kann man auch prozentuale Werte definieren, wenn die Dimensionen des Parents gesetzt wurden.
Nun werden die beiden erstellten und importierten Komponenten präsentiert. Jedoch wird die jeweilige Definition eines Stylesheets ausgelassen, da sich diese analog zum zuvor präsentieren Stylesheet verhält. Es wird mit dem UserForm angefangen:
export default function UserForm(props: { addUser: (user: IUser) => void; }): React.ReactElement { const [insertedName, setInsertedName] = useState(""); function handleSubmit() { const newUser = { id: Math.floor(Math.random() * 1000000), name: insertedName, } as IUser; props.addUser(newUser); setInsertedName(""); } return ( <View> <Text>Add a User:</Text> <View style={Styles["form-container"]}> <TextInput style={Styles.input} value={insertedName} onChangeText={setInsertedName} onSubmitEditing={handleSubmit} keyboardType="default" placeholder="Insert a Name" /> <Button title="Add User" onPress={handleSubmit} /> </View> </View> ); }
Abbildung 6: JSX des UserForms.
Diese Komponente erwartet eine Funktion zum Hinzufügen eines Users als Prop und beinhaltet selbst eine Funktion zum Handhaben des Absendens des Inputs. Im zurückgegebenen Template sind neben der zuvor präsentieren View weitere Komponenten von React Native verwendet worden. Dabei haben die Komponenten eigene Eigenschaften, die sich ähnlich zu den HTML-Gegenstücken verhalten. Beispielsweise besitzt der TextInput die Eigenschaft onSubmitEditing, welche eine Funktion annimmt, die aufgerufen wird, wenn der TextInput abgesendet wird. Nun folgt die Vorstellung der Liste für Nutzer:
export default function UserForm(props: { addUser: (user: IUser) => void; }): React.ReactElement { const [insertedName, setInsertedName] = useState(""); function handleSubmit() { const newUser = { id: Math.floor(Math.random() * 1000000), name: insertedName, } as IUser; props.addUser(newUser); setInsertedName(""); } return ( <View> <Text>Add a User:</Text> <View style={Styles["form-container"]}> <TextInput style={Styles.input} value={insertedName} onChangeText={setInsertedName} onSubmitEditing={handleSubmit} keyboardType="default" placeholder="Insert a Name" /> <Button title="Add User" onPress={handleSubmit} /> </View> </View> ); }
Abbildung 7: Die UserList-Komponente.
Diese Komponente dient nur der Darstellung einer Liste von Nutzern. Jeder Nutzer wird mit einem Bild und einem Namen repräsentiert. Diese Eigenschaften werden in der renderUserName-Funktion gerendert. Interessant ist dabei die Source des verwendeten Image-Bausteins. Diese nimmt ein Objekt an, welches zur Konfiguration verwendet werden kann. Beispielsweise können Header oder ein Body spezifiziert werden. Zum Beispiel könnte in den Header ein Token für die Authentifizierung geschrieben werden. Das Ergebnis für diese Ansicht sieht wie folgt aus:
Abbildung 8: Die Liste von Nutzern auf dem iPhone.
Erstellung der Hilfe
Diese Komponente soll einen Text anzeigen und dabei das Modul für Animationen namens Animated, von React Native verwenden. Die folgende Abbildung präsentiert die Komponente:
export default function Help(): React.ReactElement { const fadeIn = useRef(new Animated.Value(0)).current; const translateX = useRef(new Animated.Value(1)).current; useEffect(() => { const fadeInAnimation = Animated.timing(fadeIn, { toValue: 1, duration: 1000, useNativeDriver: true, easing: Easing.bounce, } as Animated.TimingAnimationConfig); const translateXAnimation = Animated.timing(translateX, { toValue: 160, duration: 500, useNativeDriver: true, easing: Easing.circle, } as Animated.TimingAnimationConfig); Animated.sequence([fadeInAnimation, translateXAnimation]).start(); }, [fadeIn]); return ( <View style={{ position: "relative" }}> <Animated.Text style={{ opacity: fadeIn, transform: [{ translateX }] }}> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet </Animated.Text> </View> ); }
Abbildung 9: Die Hilfe-Komponente.
Diese Komponente beinhaltet zwei Animationen, die sequenziell ausgeführt werden. Als Erstes wird der initiale Wert definiert. Im UseEffect-Hook werden die Endwerte und die Dauer der Animation definiert. Beide Animationen werden in ein Array verpackt und der Methode Animated.sequence übergeben. Zum Schluss wird die Sequenz gestartet. Damit die Animationen auch Anwendung finden, werden die Werte an die entsprechenden Styles übergeben. Für den Fade-in-Effekt wird die Opacity des Elements gesetzt. Dabei wird für die Animation kein einfacher Text-Baustein, sondern ein von Animated angebotenen Baustein Animated.Text verwendet.
Routing
Um zwischen den Ansichten wechseln zu können, wird React Navigation (React Navigation, 2021) verwendet. Dieses wird wie folgt in die App.tsx Datei integriert:
export default function App(): React.ReactElement { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Index" component={Index} options={{ title: "Hello to your World" }} ></Stack.Screen> <Stack.Screen name="Users" component={UserScreen} options={{ title: "Users" }} ></Stack.Screen> <Stack.Screen name="Help" component={Help} options={{ title: "Help" }} ></Stack.Screen> </Stack.Navigator> </NavigationContainer> ); }
Abbildung 10: App.tsx mit Routing.
Als Erstes wird ein Stack Navigator initialisiert, welcher den Navigator und die Screens bereitstellt. Diese werden in einem NavigationContainer eingebunden. Jeder Screen erhält dabei einen Namen und eine Komponente zugewiesen. Zudem können weitere Optionen, wie zum Beispiel ein Titel für die jeweilige Seite angegeben werden. Durch die Integration wird zusätzlich die folgende Komponente im oberen Bildschirmabschnitt in IOS hinzugefügt:
Abbildung 11: Navigation auf dem iPhone.
Die Index-Seite
Bis hierher hat das System drei Seiten, zwischen denen nicht navigiert werden kann. Für die Navigation wird die Index-Seite verwendet. Dieses bietet zwei Buttons an, die die jeweiligen Seiten öffnen. Der Code ist in der folgenden Abbildung zu finden:
export default function Index(props: { navigation: NavigationProp<NavigatorParamList>; }): React.ReactElement { return ( <View style={{ width: 300, flexDirection: "row", justifyContent: "space-evenly", }} > <Button title="Users" onPress={() => props.navigation.navigate("Users")} /> <Button title="Help" onPress={() => props.navigation.navigate("Help")} /> </View> ); }
Abbildung 12: Die Index-Seite.
Builden für Android
Die Schritte zum Generieren einer AAB werden im Folgenden beschrieben. Diese basiert auf der Anleitung, die in den Docs zu finden ist.
- Erstellung eines Keys über das Keytool von Java (dies ist im bin-Ordner der Java-Installation zu finden). Dafür wird folgendes Kommando im Ordner ausgeführt:
- keytool -genkeypair -v -storetype PKCS12 -keystore react-native-intrnal.keystore -alias react-native-internal-alias -keyalg RSA -keysize 2048 -validity 10000
- Navigation in den Android-Ordner des Projekts
- Setzen der Variablen in der gradle.properties Datei. In der folgenden Abbildung sind die zusetzenden präsentiert. Wenn diese Felder nicht vorhanden sind, dann sollen diese ergänzt werden.
MYAPP_UPLOAD_STORE_FILE=react-native-internal.keystore MYAPP_UPLOAD_KEY_ALIAS=react-native-internal-alias MYAPP_UPLOAD_STORE_PASSWORD=password123 MYAPP_UPLOAD_KEY_PASSWORD=password123
Abbildung 13: Ergänzungen zu gradle.properties.
- Ergänzung der Gradle-Config unter ./app/build.gradle um die folgenden Felder:
android { ... defaultConfig { ... } signingConfigs { release { if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) { storeFile file(MYAPP_UPLOAD_STORE_FILE) storePassword MYAPP_UPLOAD_STORE_PASSWORD keyAlias MYAPP_UPLOAD_KEY_ALIAS keyPassword MYAPP_UPLOAD_KEY_PASSWORD } } } buildTypes { release { ... signingConfig signingConfigs.release } } }
Abbildung 14: Ergänzungen zu ./app/build.gradle.
- Wenn das Android SDK nicht gefunden wird, muss auf dieses manuell verwiesen werden. Hierfür wurde eine Datei local.properties im Android-Ordner erstellt. Diese enthält den folgenden String: dir = C:\\Users\\admin\\AppData\\Local\\Android\\sdk
- Wenn Java nicht gefunden wurde, dann muss die gradle.properties Datei ergänzt werden. Es muss der folgende String hinzugefügt werden: gradle.java.home=C:\\Program Files\\Java\\jdk-15.0.2
- Generierung der AAB, indem im Android-Ordner der folgende Befehl ausgeführt wird:
$ ./gradlew bundleRelease
Abbildung 15: Befehl zum Builden für Android.
Wenn es zu keinen weiteren Problemen kommt, wird nun eine AAB generiert, die im Store hochgeladen werden kann.
React Native und Windows
React Native unterstützt out of the box weder Windows noch Mac. Um diese Plattformen zu unterstützen, wird eine Erweiterung von Microsoft namens React Native for Windows + Mac verwendet (Microsoft, 2021b). Um diese Erweiterung verwenden zu können, wird im Root-Ordner der folgende Befehl ausgeführt:
$ npx react-native-windows-init --overwrite
Abbildung 16: Befehl zum initialisieren von React Native für Windows.
Entwicklung In VS Code
Um in VS Code entwickeln zu können, werden als erstes das Plugin React Native Tools für VS Code installiert. Im Anschluss wird die Datei ./vscode/launch.json erstellt und mit den folgenden Inhalten gefüllt:
{ "version": "0.2.0", "configurations": [ { "name": "Debug Windows", "cwd": "${workspaceFolder}", "type": "reactnative", "request": "launch", "platform": "windows" } ] }
Abbildung 17: launch.json.
Nun kann F5 gedrückt werden und es öffnet sich nach einiger Zeit ein natives Windows-Fenster mit den Inhalten.
Inkompatibilität der Bibliotheken
Wenn der zuvor erstellte Prototyp für Windows gestartet werden soll, wird ein Fehler, der durch die verwendete Navigation entsteht, angezeigt. Dieser Fehler führt einem eine Limitierung des gewählten Ansatzes vor Augen: Es wird zwar mit einer Codebasis für mehrere Plattformen entwickelt, jedoch ist nicht jedes verwendete Package mit jeder Plattform kompatibel. Da der Fokus hier auf das Builden für Windows gelegt wird, wird der Einfachheit wegen der Navigation für Windows entfernt. Dies geht wie folgt in der App.tsx:
import React from 'react'; import {Platform} from 'react-native'; import {NavigationContainer} from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import UserScreen from './pages/user-screen'; import Help from './pages/help'; import Index from './pages/index'; const Stack = createNativeStackNavigator(); const App = () => { if (Platform.OS === 'windows') { return <UserScreen />; } return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Index" component={Index} options={{title: 'Hello to your World'}} /> <Stack.Screen name="Users" component={UserScreen} options={{title: 'Users'}} /> <Stack.Screen name="Help" component={Help} options={{title: 'Help'}} /> </Stack.Navigator> </NavigationContainer> ); };
Abbildung 18: App.tsx mit Anpassungen für Windows.
Im Rendering wird auf die Plattform geprüft. Wenn es sich um Windows handelt, wird nur die UserScreen Komponente gerendert. Sonst wird alles wie gehabt gerendert.
Builden für Windows
Für das Builden wird Visual Studio verwendet. Dafür müssen die folgenden Schritte durchgeführt werden, welche sich an der Anleitung von Microsoft orientieren:
- Öffnen die Windows-Solution in Visual Studio.
- Auswahl der Release-Konfiguration.
- Builden der Solution (z. B. durch Rechtsklick auf die Solution und Build auswählen)
- Für das Generieren der Appx einen Rechtsklick auf das Projekt und wähle wie folgt aus:
- Project / Publish / Create App Packages
- Beim Erstellen wird nach einem Zertifikat verlangt. Ein temporäres Zertifikat kann im Dialog selbst erstellt werden. Jedoch muss dieses auf dem System installiert und als vertrauenswürdig definiert werden.
Wenn es zu Problemen kommt, kann es an der installierten SDK für Windows liegen. Über den Visual Studio Installer kann die gewünschte Version, zum Beispiel 10.0.18362.0, nach installiert werden.
Pros & Cons von React Native
Das Sprichwort „Es ist nicht alles Gold was glänzt“, trifft auch auf React Native zu. Daher werden in diesem Abschnitt die Vor- und Nachteile dieses Frameworks beleuchtet:
Die Vorteile
- React Native bietet einen Hot Reload an: Änderungen werden nach dem Speichern sofort übernommen.
- Wenn Expo verwendet wird, kann ohne größeren Aufwand auf den nativen Geräten entwickelt und gedebuggt werden.
- Es wird eine Codebasis für mehrere Plattformen geschrieben. Dadurch können Ressourcen wie zum Beispiel Zeit gespart werden.
- Es kann bei Bedarf ergänzender plattformspezifischer Code geschrieben werden (React Native, 2021c).
- Ein Webentwickler, der React kennt, kann dieses Framework schnell aufgreifen. Somit wird unter anderem Zeit für die Einarbeitung gespart.
Die Nachteile
- Nicht jede Bibliothek kann verwendet werden. Ein Beispiel ist das verwendete Routing-Package, welches nicht in Windows lief. Jedoch bietet React Native eine Übersicht über die kompatiblen Packages und deren Zielplattformen an.
- Auch wenn ein Webentwickler mehrere Plattformen bedienen kann, kann es vorkommen, dass plattformspezifischer Code benötigt wird. Wenn dieser Fall eintritt, wird ein Entwickler mit entsprechenden Kenntnissen benötigt.
- Es kann zu plattformspezifischen Verhalten kommen. In dem erstellten Prototypen war dies auch der Fall. Beispielsweise wurde auf Android nach dem Absenden des Eingabefelds dieses ohne Probleme geleert. Beim Verwendeten iPhone wurde jedoch nach dem Absenden gelegentlich automatisch das Feld mit Eingaben aus dem Autocomplete befüllt, wenn das eingegebene Wort nicht bekannt war.
- Für React Native existiert kein MSAL-Package von Microsoft, welches die Authentifizierung mit Azure ermöglicht. Es existiert zwar ein POC für Android, jedoch wird explizit darauf hingewiesen, diesen nicht in der Produktion zu verwenden (Github, 2021d).
Fazit
Mit React Native lassen sich mit einer Codebasis mehrere Plattformen bedienen. Dabei wird React sowie plattformagnostische Komponenten verwendet. Während der Entwicklung empfiehlt es sich, ein Gerät der Zielplattform zu verwenden. Beispielsweise kann bei Expo ohne Probleme ein Gerät über beispielsweise WLAN für die Entwicklung verwenden. Zusätzlich kann ein Entwickler mit React-Erfahrungen sofort loslegen, da sich nur die Bausteine unterscheiden. Jedoch sind die Bausteine in der Dokumentation gut beschrieben und werden mit interaktiven Beispielen vorgestellt, sodass sich relativ einfach eingearbeitet werden kann. Jedoch ist bei der Verwendung von React Native zu beachten, dass nicht jede Library verwendet werden kann und dass, obwohl mit einer Code-Basis mehrere Plattformen bedient werden können, für nativen Code ein entsprechender Entwickler benötigt wird. Abschließend ist zu sagen, dass in diesem Artikel nur Builds für Android und Windows vorgestellt wurden. Jedoch sind auch Builds für IOS, Mac und das Web denkbar. Für das Builden für IOS und Mac wird ein Mac benötigt. Wenn man jedoch auch das Web bedienen möchte, dann kann React native Web (Github, 2021c) verwendet werden.
Referenzen
Android Studio (2021). https://developer.android.com/studio. (Stand: 20.09.2021).
Github (2021a). https://github.com/facebook/react-native. (Stand: 20.09.2021).
Github (2021b). https://github.com/expo/expo. (Stand: 20.09.2021).
Github (2021c). https://github.com/necolas/react-native-web. (Stand: 20.09.2021).
Github (2021d). https://github.com/AzureAD/microsoft-authentication-library-for-js/packages/292089#:~:text=MSAL%20for%20React%20Native%20is%20a%20proof%20of,library%20is%20only%20available%20for%20the%20Android%20platform. (Stand: 20.09.2021).
Java (2021). https://www.java.com/de/. (Stand: 20.09.2021).
Microsoft (2021a). https://visualstudio.microsoft.com/de/. (Stand: 20.09.2021).
Microsoft (2021b). https://microsoft.github.io/react-native-windows/. (Stand: 20.09.2021).
NodeJs (2021). https://nodejs.org/en/. (Stand: 20.09.2021).
NPM (2021). https://www.npmjs.com/. (Stand: 20.09.2021).
React Native (2021a). https://reactnative.dev/. (Stand: 20.09.2021).
React Native (2021b). https://reactnative.dev/docs/components-and-apis. (Stand: 20.09.2021).
React Native (2021c). https://reactnative.dev/docs/platform-specific-code. (Stand: 20.09.2021).
React Navigation (2021). https://reactnavigation.org/. (Stand: 20.09.2021).
Typescript (2021). https://www.typescriptlang.org/. (Stand: 20.09.2021).