- Clone the repository with
git clone <url>
- Go into the frontend directory and install necessary packages
cd frontend && npm install
. - Install Expo on your mobile device to later test.
- Install Webpackage to run on the web
npx expo install react-dom react-native-web @expo/webpack-config
- Start application with npx expo start.
- The url or the QR-Code can be used on the mobile device to open the app.
- react native navigation has some issues when is comes to the package
react-native-safe-area-context
. Make sure to install@react-native-masked-view/masked-view
.
Wir bauen im folgenden eine Profilseite in React Native. React Native basiert auf React, jedoch mit Android/IOS optimierten Komponenten. Gewisse Verhaltensweise wie fast-refresh beim rendern unterscheiden sich von react, aber im Großen und Ganzen ist der Schritt von react zu react native kein all zu großer. Wir werden in diesem Zuge TypeScript, Code linting, testing, pre-hooks, github Actions, sowie eine Testing Liberary - in diesem Fall jest - anschauen. Ziel ist es eine eigenes mehrseitiges Profil zu haben und diesem Zuge weitere essentielle Teile des CI - CD Zyklus kennenzulernen.
- Setze ein leeres React Native Projekt mit Expo auf. Expo ist ein Tooling für Monorepos in react native. Folgender [Link] führt dich zur Installation, ersten Start mit Expo Go und der Dateistruktur. Arbeite dich etwas in die Dokumentation rein und starte deine App auf deinem Handy. Ändere die Anzeige zu einer einfachen Überschrift.
- Du kannst bereits deine App auf deinem Handy starten. Expo bietet verschiedene Debugging, Monitor und Interspecter an um die App zu untersuchen. Lese dich etwas hier zum Developer Menu ein, wenn du möchtest. Wir werden im nächsten Schritt jedoch auch die Browservariante nutzen.
- Versuche nach dem Start von deiner App die den dev-server für den Browser aufzurufen. Du wirst einen Dependecy Error zurückbekommen. Was musst du noch installieren?
- Du bekommst einen entsprechenden Zirkel angezeigt, solange die App lädt. Dies nennt sich der sogenannte Splash-Screen. Diesen kann man mit Hilfe von Figmaprototyping anpassen, sodass ein entsprechender Hintergrund vorgeladen wird. Außerdem ist es möglich die späteren Logos für die App anzupassen. Erstelle entsprechende icons und splashscreen mit Hilfe der Dokumentation-splash und Dokumentation-icons
- Da auf Android und Ios ein bestimmter Bereich reserviert ist (z.B Statusbar bei Android) möchte man nur innerhalb eines sogenannten safe-are-space die App platzieren. Erkundinge dich nach dem
<SaveAreaProvider></SaveAreaProvider>
- Wir beginnen zuerst, indem wir eine custom theme mit react-native-paper initialisieren. React native paper ist ein UI-Framework ähnlich wie MUI auf das Material Design beruht. Dein Ziel sollte sein eine eigene Theme (z.b fontSize...) basierend auf der default Theme von MD3LightTheme für die gesamte App bereitzustellen.
- Es gibt die Möglichkeit custom fonts in die App zu laden und diese in die custom theme zu übergeben. Erkundige dich wie du fonts in react native und expo laden kannst.
- Nun kannst du deine eigene Startseite (die Seite auf der NutzerInnen zuerst landen) erstellen. Es gibt hierbei keine Einschränkung, jedoch solltest du beachten nicht zuviel einzubauen, sondern erst in weiteren Seiten. Ein schöner Hintergrund, ein Zitat/Motivation mit eventuellem Effekt reichen erstmal aus. Erstelle die benötigten Komponenten und überführe diese in eine
Home.jsx
Komponete. Diese wird zuletzt in dieApp.jsx
übergeben. - Falls du Animationen nutzen möchtest, eignen sich react-reanimated oder moti ganz gut.
- Erstelle nun eine einfache Navigation. Es gibt hierbei mehrere Möglichkeiten, die von react native paper und direkt von der unterliegenden Navigationsbibliothek react-navigation angeboten werden.
- Baue eine weitere Komponente, als Beispiel kann man hierfür die work experience als verschiebare Karte einbauen. Verlinke diese in den Router.
Falls du nicht initial bei dem Projektaufsatz mit npx create-expo-app **NAME**
schon bereits Typescript als Basis für dein Projekt ausgewählt hast, kannst du weiterhin TypeScript on top installieren.
- Installiere TypeScript (expo und npm sind bereits vorhanden) mit
npm install --save-dev typescript
. - Mit
npx tsc --init
kannst du im rootverzeichnis deines Projekts einetsconfig.json
mit grundlegenden Einstellungen erstellen. Diese Einstellungen steuern im wesentlichen das Verhalten des TypeScript-Compilers. - Falls die entsprechende Datei leer ist, kannst du entsprechend folgende Konfigurationseinstellungen übernehmen.
{
"compilerOptions": {
"strict": true,
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"*": ["node_modules/*", "src/*", "assets/*"]
}
},
"extends": "expo/tsconfig.base"
}
Das "extends"
property übernimmt die bereits in expo vordefinierten grundlegenden Konfigurationseinstellungen. Mit strg + Rechtsklick
kannst du dir die Konfiguration entsprechend einmal anschauen. 4. Benenne nun die Dateien in deinem src
Ordner um. Statt .js
haben diese die Endung .tsc
oder statt jsx
nun tsx
. 5. Du kannst nun eine Typüberprüfung mit npx tsc
durchführen. Stattdessen kann man auch in der package.json
ein Skriptbefehl schreiben wie z.B ts:check": "tsc --noEmit
wobei das Flag --noEmit
weggelassen werden kann, da die tsconfig.json
dies schon festlegt (zur es werden keine Compilierte js Dateien erzeugt, da wird expo dies schon für uns handhabt).
Bevor wir nun weitermachen gibt es einen kleinen Crash-Course in Typezuweisung:
Einfache Variablen kann folgend einen Typ zuweisen.
const text: string = "Hallo Welt";
Das funktioniert natürlich auch, wenn der Wert erst zur Laufzeit bestimmt wird, aber man trotzdessen schon ein bestimmten Typen erwartet:
const userInput: string = prompt("\n>>");
Um properties von Objekten zu beschreiben können wir entweder sogenannte interfaces
oder types
verwenden. Erstmal beide im in ihrer einfachen Anwendung:
*interface
interface User = {
name: string,
age: number,
neet: boolean
}
const someUsers : User[] = [
{
name: "saqib",
age : 27,
neet: true
},
{
name: "toto",
age : 10,
neet: true
},
]
types
type User = {
name: string,
age: number,
neet: boolean
}
const someUsers : User[] = [
{
name: "saqib",
age : 27,
neet: true
},
{
name: "toto",
age : 10,
neet: true
},
]
An sich erstmal die gleiche Syntax. Der Hauptunterschied liegt in Wiedernutzung (interface durch extends
) und in der Vereinigung von mehreren, schon vorhandenen Typen
interface erweiterbar (Pluspunkt in Wiederverwertbarkeit und Modularisierung)
interface User = {
name: string,
age: number,
neet: boolean
}
interface specialUsers extends User = {
imgUrl: string
}
const someUsers : User[] = [
{
name: "saqib",
age : 27,
neet: true
},
{
name: "toto",
age : 10,
neet: true
},
]
const someUserWithImg : specialUsers[] = [
{
name: "saqib",
age : 27,
neet: true,
imgUrl: "http://irgendein.dummer.link"
},
{
name: "toto",
age : 10,
neet: true,
imgUrl: "http://irgendein.dummer.link"
},
]
interface extendable (Pluspunkt in Wiederverwertbarkeit und Modularisierung)
```tsc
type User = {
name: string,
age: number,
neet: boolean
}
interface specialUsers extends User = {
imgUrl: string
}
const someUsers : User[] = [
{
name: "saqib",
age : 27,
neet: true
},
{
name: "toto",
age : 10,
neet: true
},
]
const someUserWithImg : specialUsers[] = [
{
name: "saqib",
age : 27,
neet: true,
imgUrl: "http://irgendein.dummer.link"
},
{
name: "toto",
age : 10,
neet: true,
imgUrl: "http://irgendein.dummer.link"
},
]
type intersection/union (wenn Typen manchmal zur Laufzeit klar sind oder sich ändern können)
type User = {
name: string,
age: number | string,
neet: boolean
}
const someUsers : User[] = [
{
name: "saqib",
age : "27",
neet: true
},
{
name: "toto",
age : 10,
neet: true
},
]
const someUserWithImg : specialUsers[] = [
{
name: "saqib",
age : 27,
neet: true,
imgUrl: "http://irgendein.dummer.link"
},
{
name: "toto",
age : 10,
neet: true,
imgUrl: "http://irgendein.dummer.link"
},
]
Abgesehen davon kann man mit type
auch primitive Datentypen (Abseits unseres Beispiels zu Variablen oben) und Tupel typisieren (wir werden diesen Begriff ab jetzt nutzen, um auszusagen, dass einem bestimmten Wert einen Datentypen zugeordnet wird).
type Coordinate = number | number;
type ID = string | number;
6. Wir fangen nun nach und nach an unsere Dateien mit
types
zu versehen. Zuerst wollen wir die properties mit einem jeweiligen type
versehen. Suche dir dazu deine Komponente mit den props raus. Ich gebe dir nun ein Beispiel:
type WorkingCardPropTypes = {
position: string;
years: string;
location: string;
description: string;
};
export function WorkingCard({
position,
years,
location,
description,
}: WorkingCardPropTypes): React.JSX.Element {
//CODE
}
Da props innerhalb eines Objekt spezifiziert schreiben, schreiben wir ebenfalls ein entsprechende Objekt mit den entsprechenden Schlüssel und den entsprechenden Datentypen. Da Zuweisen geschieht hier mit einem Doppeltpunkt.
....
...