Liste mit Todos
Dauer: 45 Minuten
- Daten in einem lokalen Array
- FlatList einbinden
- Übung: FlatList in eigener Datei
- Übung: FlatList stylen
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:
FlatList
importieren.- Nun kann
<FlatList/>
als Komponente im JSX-Code mit mindestens den Propsdata
undrenderItem
verwendet werden. - Im Prop
data
ist ein Array mit Listenelementen zu definieren. - Dem Prop
renderItem
wird eine Funktion übergeben, die eine Komponente zur Darstellung eines Listeneintrags liefert (wird automatisch für jedes Element indata
aufgerufen). - Bei Bedarf für die
FlatList
Abstand zum oberen Bildschirmrand mitpaddingTop
definieren.
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.
Im Web sind oft Beispiele mit FlatList
zu finden, bei denen die Komponente SafeAreaView
zum Einsatz kommt. Hierdurch wird automatisch der Abstand zum oberen Bildschirmrand erzeugt, allerdings nur für das iPhone und leider nicht auf Android-Geräten (Stand Oktober 2024).
Mit dem Package expo-constants kann plattformunabhängig ein Abstand zum oberen Bildschirmrand festgelegt werden:
npx expo install expo-constants
import Constants from 'expo-constants';
const styles = StyleSheet.create({
container: {
paddingTop: Constants.statusBarHeight,
// Rest bleibt unverändert
}
});
Ü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
.
Ü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:
Zeit für das Projekt
Die restliche Zeit kann für Fragen, Gruppengespräche oder Teamarbeit genutzt werden.