Liste mit Todos
Dauer: 20 Minuten
- Daten in einem lokalen Array
- FlatList einbinden
- Übung: FlatList in eigener Datei
- Übung: FlatList stylen
Vorstellung des Frameworks
- Installation und Einrichtung der Entwicklungsumgebung
- Prinzipien des Frameworks (Projektstruktur, Komponenten/Widgets, …)
- App mit einem Screen: UI-Elemente, Layout, Interaktion und State
- Daten lokal speichern
- Navigation zwischen mehreren Screens
Daten in einem lokalen Array
In fast jeder App werden Daten verwaltet, in unserem Beispiel sind dies u.a. die Todos. Je nach Umfang und Komplexität der Daten wird dafür auf längere Sicht eine Datenbank oder eine andere Form der persistenten Speicherung benötigt.
Zunächst konzentrieren wir uns auf das UI und werden noch keine Datenbank in unserer App einsetzen. Dennoch macht es Sinn, im Code die Daten vom UI zu trennen, damit eine spätere Einbindung einer Datenbank leichter umzusetzen ist. Hierzu definieren wir ein einfaches Array bestehend aus Strings und weisen dies einer Konstanten außerhalb der Funktionskomponente zu:
const todos = ['Einkaufen', 'Sport', 'React Native lernen'];
export default function App() {
return (
<View style={styles.container}>
<Todo>Einkaufen</Todo>
<Todo>Sport</Todo>
<Todo>React Native lernen</Todo>
<StatusBar style="auto" />
</View>
);
}Nun können wir die Todos aus dem todos-Array verwenden, indem mir mit der Array-Funktion map zu jedem String die passende <Todo>-Komponente erstellen:
const todos = ['Einkaufen', 'Sport', 'React Native lernen'];
export default function App() {
return (
<View style={styles.container}>
{todos.map((todo) => (
<Todo>{todo}</Todo>
))}
<StatusBar style="auto" />
</View>
);
}Dabei sind die geschweiften Klammern im JSX-Code zu beachten, welche die Verwendung von JavaScript-Code signalisieren.
Bei Bedarf kann die Funktionsweise von map und Pfeilfunktionen in JavaScript kurz erläutert werden (JavaScript-Code in der Browser-Konsole, Whiteboard, ChatGPT, …).
Todos als JavaScript-Objekte
Wir erhalten nun diese Warnung in der App:

Wenn React (Native) iterativ mehrere Komponenten als eine Art Liste erzeugt, dann wird erwartet,
dass jede Komponente eindeutig identifizierbar ist. Dies wird zu Optimierungszwecken benötigt,
wenn sich z.B. die Reihenfolge in der Liste ändert. In React (Native) wird dazu in jeder Komponente
ein key-prop mit einem eindeutigen Wert definiert, wie hier angedeutet:
<Todo key={id}>{todo}</Todo>Neben key gibt es weitere „reservierte“ Props, die nicht für eigene Zwecke genutzt werden sollten (u.a. ref).
Um diese Anforderung in unserer App zu erfüllen, könnten wir die Todos im Array als
JavaScript-Objekte mit eindeutigen Werten in einer id-Eigenschaft deklarieren:
const todos = [
{ id: 1, text: 'Einkaufen' },
{ id: 2, text: 'Sport' },
{ id: 3, text: 'React Native lernen' },
];
export default function App() {
return (
<View style={styles.container}>
{todos.map((todo) => (
<Todo key={todo.id}>{todo.text}</Todo>
))}
<StatusBar style="auto" />
</View>
);
}Wichtig ist, dass die Todo-Komponenten nun passend zu den JavaScript-Objekten im Array
deklariert werden, d.h. auf den Text des Todo-Objekts muss nun mit todo.text zugeriffen
werden. Zusätzlich setzen wir key-Prop mit der ID:
<Todo key={todo.id}>{todo.text}</Todo>Damit sollte die Warnung verschwinden.
FlatList einbinden
React Native stellt mit FlatList eine Komponente bereit, mit der beliebig viele Elemente in einer scrollbaren Liste dargestellt werden können. Um FlatList zu verwenden, sind folgende Schritte nötig:
FlatListimportieren.- Nun kann
<FlatList/>als Komponente im JSX-Code mit mindestens den PropsdataundrenderItemverwendet werden. - Im Prop
dataist ein Array mit Listenelementen zu definieren. - Dem Prop
renderItemwird eine Funktion übergeben, die eine Komponente zur Darstellung eines Listeneintrags liefert (wird automatisch für jedes Element indataaufgerufen). - Bei Bedarf für die
FlatListAbstand zum oberen Bildschirmrand mitpaddingTopdefinieren.
Wir können unsere App mit FlatList wie folgt umschreiben:
import { FlatList, StyleSheet, View } from 'react-native';
import Todo from './components/Todo';
const todos = [
{ id: 1, text: 'Einkaufen' },
{ id: 2, text: 'Sport' },
{ id: 3, text: 'React Native lernen' },
];
export default function App() {
return (
<View style={styles.container}>
<FlatList
data={todos}
renderItem={({ item }) => (
<Todo key={item.id}>{item.text}</Todo>
)}
/>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
paddingTop: 50, // <-- Abstand zum oberen Bildschirmrand
},
});Zur Laufzeit wird die Funktion im Prop renderItem automatisch für jedes Element des Arrays aufgerufen, das im Prop data übergeben wird. Die Funktion in renderItem erhält ein Objekt als Parameter, dessen Eigenschaft item das anzuzeigende Array-Element enthält. Im Code-Beispiel wird dies mit { item } destrukturiert.
Zu beachten ist auch der Abstand zum oberen Bildschirmrand, den wir mit paddingTop: 50 im style-Objekt festlegen, damit die Liste komplett sichtbar ist.
Unterschiedliche Displaygrößen auf iPhones und Android-Geräten mit verschiedenen Eigenschaften wie z.B. iPhone-Notch, Safe Area und Status Bar erfordern oft eine genauere Behandlung des Abstands zum oberen Bildschirmrand.
Ein Beispiel einer plattformübergreifenden Lösung ist das Package react-native-safe-area-context
Infos zur Verwendung in Expo-Apps: https://docs.expo.dev/versions/latest/sdk/safe-area-context/
npx expo install react-native-safe-area-contextWenn wir in unserer App SafeAreaView als äußerste Komponente
im UI-Baum verwenden, dann wird der Abstand zum oberen Bildschirmrand
automatisch korrekt gesetzt:
import { SafeAreaView } from 'react-native-safe-area-context';
// restlicher Code unverändert
export default function App() {
return (
<SafeAreaView style={styles.container}>
<FlatList
data={todos}
renderItem={({ item }) => (
<Todo key={item.id}>{item.text}</Todo>
)}
/>
<StatusBar style="auto" />
</SafeAreaView>
);
}Übung: FlatList in eigener Datei
Erstellen Sie eine eigene Komponente TodoList für die FlatList in einer neuen Datei components/TodoList.jsx und verwenden Sie diese in App.js.
Lösung:
👉Übung: FlatList stylen
Ergänzen Sie die TodoList-Komponente mit Styles, sodass die Liste auf den ganzen Bildschirm ausgedehnt wird und linksbündig erscheint.
Recherchieren Sie außerdem in der Dokumentation zu FlatList (https://reactnative.dev/docs/flatlist ), wie Sie mit dem FlatList-Prop namens ItemSeparatorComponent einen Trennstrich zwischen zwei Todos in der Liste anzeigen können:
