Pagination und Sortierung mit searchCriteria
Pagination und Sortierung mit searchCriteria
~14 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
GENAU wie im React-Web-Tutorial nutzen wir searchCriteria für Pagination und Sortierung – in React Native kombinieren wir das zusätzlich mit FlatLists eingebautem "Nachladen beim Scrollen" statt Buttons.
fetchProducts() um Pagination und Sortierung erweitern
const BASE_URL = process.env.EXPO_PUBLIC_MAGENTO_BASE_URL;
const ACCESS_TOKEN = process.env.EXPO_PUBLIC_MAGENTO_ACCESS_TOKEN;
const SEITENGROESSE = 12;
async function magentoFetch(path) {
const response = await fetch(`${BASE_URL}${path}`, {
headers: { Authorization: `Bearer ${ACCESS_TOKEN}` },
});
if (!response.ok) {
throw new Error(`Magento API Fehler: ${response.status}`);
}
return response.json();
}
export async function fetchProducts({ seite = 1, sortierFeld = 'name', richtung = 'ASC' } = {}) {
const params = new URLSearchParams({
'searchCriteria[pageSize]': SEITENGROESSE,
'searchCriteria[currentPage]': seite,
'searchCriteria[sortOrders][0][field]': sortierFeld,
'searchCriteria[sortOrders][0][direction]': richtung,
});
const data = await magentoFetch(`/products?${params.toString()}`);
return {
produkte: data.items,
gesamtAnzahl: data.total_count,
seitenAnzahl: Math.ceil(data.total_count / SEITENGROESSE),
};
}Nachladen beim Scrollen: onEndReached
Statt "Weiter"/"Zurück"-Buttons wie im React-Web-Tutorial nutzen wir hier das für mobile Listen typischere Muster: automatisches Nachladen der nächsten Seite, sobald der Nutzer near dem Ende der Liste scrollt.
import { useEffect, useState } from 'react';
import { FlatList, Text, View, ActivityIndicator, StyleSheet } from 'react-native';
import { fetchProducts } from '../api/magentoApi';
export default function ProductListScreen() {
const [produkte, setProdukte] = useState([]);
const [seite, setSeite] = useState(1);
const [seitenAnzahl, setSeitenAnzahl] = useState(1);
const [ladend, setLadend] = useState(true);
const [ladeMehr, setLadeMehr] = useState(false);
useEffect(() => {
async function ersteSeiteLaden() {
const ergebnis = await fetchProducts({ seite: 1 });
setProdukte(ergebnis.produkte);
setSeitenAnzahl(ergebnis.seitenAnzahl);
setSeite(1);
setLadend(false);
}
ersteSeiteLaden();
}, []);
async function naechsteSeiteLaden() {
if (ladeMehr || seite >= seitenAnzahl) {
return; // schon am Laden oder schon auf der letzten Seite
}
setLadeMehr(true);
const naechsteSeite = seite + 1;
const ergebnis = await fetchProducts({ seite: naechsteSeite });
setProdukte((bisherige) => [...bisherige, ...ergebnis.produkte]);
setSeite(naechsteSeite);
setLadeMehr(false);
}
if (ladend) {
return <ActivityIndicator style={styles.zentriert} size="large" />;
}
return (
<FlatList
data={produkte}
keyExtractor={(produkt) => produkt.sku}
renderItem={({ item }) => (
<View style={styles.zeile}>
<Text style={styles.name}>{item.name}</Text>
<Text>{item.price} €</Text>
</View>
)}
onEndReached={naechsteSeiteLaden}
onEndReachedThreshold={0.5}
ListFooterComponent={ladeMehr ? <ActivityIndicator /> : null}
/>
);
}
const styles = StyleSheet.create({
zentriert: { flex: 1, justifyContent: 'center' },
zeile: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#eee' },
name: { fontWeight: 'bold', marginBottom: 4 },
});onEndReachedThreshold={0.5} löst onEndReached aus, sobald noch 50% der Listenhöhe bis zum tatsächlichen Ende übrig sind – so beginnt das Nachladen BEVOR der Nutzer das Ende wirklich erreicht, was sich flüssiger anfühlt.
Achtung: Der ladeMehr-Schutz in naechsteSeiteLaden() ist WICHTIG: FlatList kann onEndReached unter Umständen MEHRFACH kurz hintereinander auslösen (z. B. beim schnellen Scrollen) – ohne diesen Schutz würden mehrere parallele Anfragen für dieselbe Seite starten und Duplikate in die Liste einfügen.