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:

Warnung bei fehlendem key-prop

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 Props data und renderItem 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 in data aufgerufen).
  • Bei Bedarf für die FlatList Abstand zum oberen Bildschirmrand mit paddingTop 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:

FlatList mit Trennstrich

👉

Zeit für das Projekt

Die restliche Zeit kann für Fragen, Gruppengespräche oder Teamarbeit genutzt werden.