Wat is FlatList?
FlatList is een component om efficiënt lange lijsten te renderen in React Native. Het gebruikt lazy loading - alleen zichtbare items worden gerenderd.
Waarom FlatList gebruiken?
- Performance: Rendert alleen zichtbare items
- Scroll: Automatisch scrollable
- Lazy loading: Nieuwe items worden geladen tijdens scrollen
- Refresh: Ingebouwde pull-to-refresh functionaliteit
Gebruik GEEN .map() voor lange lijsten!
Bij .map() worden alle items direct gerenderd, wat traag is. FlatList rendert alleen wat zichtbaar is.
Basis Gebruik
Simpel Voorbeeld
import { FlatList, View, Text, StyleSheet } from 'react-native';
const DATA = [
{ id: '1', title: 'Item 1' },
{ id: '2', title: 'Item 2' },
{ id: '3', title: 'Item 3' },
];
export default function App() {
return (
<FlatList
data={DATA}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
/>
);
}
const styles = StyleSheet.create({
item: {
padding: 20,
borderBottomWidth: 1,
borderBottomColor: '#ddd',
},
});
De 3 vereiste props:
data- Array met je datakeyExtractor- Functie die unieke key returnedrenderItem- Functie die elk item rendert
Met Echte Data
import { FlatList, View, Text, StyleSheet } from 'react-native';
const USERS = [
{ id: 1, name: 'Jan Jansen', email: 'jan@example.com' },
{ id: 2, name: 'Piet Pietersen', email: 'piet@example.com' },
{ id: 3, name: 'Klaas Klaassen', email: 'klaas@example.com' },
];
export default function UserList() {
const renderUser = ({ item }) => (
<View style={styles.userCard}>
<Text style={styles.name}>{item.name}</Text>
<Text style={styles.email}>{item.email}</Text>
</View>
);
return (
<FlatList
data={USERS}
keyExtractor={(item) => item.id.toString()}
renderItem={renderUser}
/>
);
}
const styles = StyleSheet.create({
userCard: {
backgroundColor: 'white',
padding: 15,
marginVertical: 8,
marginHorizontal: 16,
borderRadius: 8,
shadowColor: '#000',
shadowOpacity: 0.1,
shadowRadius: 3,
elevation: 2,
},
name: {
fontSize: 18,
fontWeight: 'bold',
},
email: {
fontSize: 14,
color: '#666',
marginTop: 4,
},
});
Belangrijke Props
data
De array met items die je wilt renderen.
data={USERS}
keyExtractor
Functie die een unieke key returned voor elk item.
keyExtractor={(item) => item.id.toString()}
Let op: Key moet een string zijn! Gebruik .toString() als je ID een nummer is.
renderItem
Functie die elk item rendert. Krijgt een object met item en index.
renderItem={({ item, index }) => (
<View>
<Text>{index + 1}. {item.name}</Text>
</View>
)}
ListEmptyComponent
Wat te tonen als de lijst leeg is.
ListEmptyComponent={() => (
<View style={styles.empty}>
<Text>Geen items gevonden</Text>
</View>
)}
ListHeaderComponent
Component bovenaan de lijst.
ListHeaderComponent={() => (
<View style={styles.header}>
<Text style={styles.headerText}>Mijn Lijst</Text>
</View>
)}
ListFooterComponent
Component onderaan de lijst.
ListFooterComponent={() => (
<View style={styles.footer}>
<Text>Einde van de lijst</Text>
</View>
)}
Styling
ItemSeparatorComponent
Scheiding tussen items.
<FlatList
data={DATA}
keyExtractor={(item) => item.id}
renderItem={renderItem}
ItemSeparatorComponent={() => (
<View style={styles.separator} />
)}
/>
const styles = StyleSheet.create({
separator: {
height: 1,
backgroundColor: '#ddd',
},
});
contentContainerStyle
Styling voor de container van alle items.
<FlatList
data={DATA}
keyExtractor={(item) => item.id}
renderItem={renderItem}
contentContainerStyle={styles.listContainer}
/>
const styles = StyleSheet.create({
listContainer: {
padding: 16,
},
});
numColumns
Meerdere kolommen (grid layout).
<FlatList
data={DATA}
keyExtractor={(item) => item.id}
renderItem={renderItem}
numColumns={2}
/>
const styles = StyleSheet.create({
item: {
flex: 1,
margin: 8,
padding: 20,
backgroundColor: 'white',
},
});
Pull to Refresh
Laat gebruikers de lijst verversen door naar beneden te trekken.
import { useState } from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';
export default function App() {
const [data, setData] = useState([
{ id: 1, title: 'Item 1' },
{ id: 2, title: 'Item 2' },
]);
const [refreshing, setRefreshing] = useState(false);
const onRefresh = () => {
setRefreshing(true);
// Simuleer data ophalen
setTimeout(() => {
setData([
{ id: 1, title: 'Nieuwe Item 1' },
{ id: 2, title: 'Nieuwe Item 2' },
{ id: 3, title: 'Nieuwe Item 3' },
]);
setRefreshing(false);
}, 2000);
};
return (
<FlatList
data={data}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
refreshing={refreshing}
onRefresh={onRefresh}
/>
);
}
const styles = StyleSheet.create({
item: {
padding: 20,
borderBottomWidth: 1,
borderBottomColor: '#ddd',
},
});
Pull to Refresh props:
refreshing- Boolean die aangeeft of er gerefresht wordtonRefresh- Functie die wordt aangeroepen bij refresh
SectionList
SectionList is vergelijkbaar met FlatList, maar met secties en headers.
Voorbeeld
import { SectionList, View, Text, StyleSheet } from 'react-native';
const DATA = [
{
title: 'Groenten',
data: ['Wortel', 'Broccoli', 'Tomaat'],
},
{
title: 'Fruit',
data: ['Appel', 'Banaan', 'Sinaasappel'],
},
];
export default function App() {
return (
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item}</Text>
</View>
)}
renderSectionHeader={({ section: { title } }) => (
<View style={styles.header}>
<Text style={styles.headerText}>{title}</Text>
</View>
)}
/>
);
}
const styles = StyleSheet.create({
header: {
backgroundColor: '#f5f5f5',
padding: 10,
},
headerText: {
fontSize: 18,
fontWeight: 'bold',
},
item: {
padding: 15,
borderBottomWidth: 1,
borderBottomColor: '#ddd',
},
});
SectionList props:
sections- Array met secties (in plaats van data)renderSectionHeader- Rendert section headersrenderItem- Rendert items (zelfde als FlatList)
Tips & Performance
1. Gebruik keyExtractor correct
// GOED
keyExtractor={(item) => item.id.toString()}
// FOUT - index is niet uniek genoeg
keyExtractor={(item, index) => index.toString()}
2. Gebruik getItemLayout voor betere performance
Als al je items dezelfde hoogte hebben:
<FlatList
data={DATA}
getItemLayout={(data, index) => ({
length: 50, // Hoogte van elk item
offset: 50 * index,
index,
})}
/>
3. Vermijd anonieme functies in renderItem
// SLECHT - nieuwe functie bij elke render
<FlatList
renderItem={({ item }) => <Item data={item} />}
/>
// GOED - functie wordt hergebruikt
const renderItem = ({ item }) => <Item data={item} />;
<FlatList renderItem={renderItem} />
4. Gebruik windowSize voor grote lijsten
<FlatList
data={HUGE_DATA}
windowSize={10}
/>
Standaard is windowSize 21. Lagere waarde = betere performance, maar meer kans op witte ruimte tijdens scrollen.
5. maxToRenderPerBatch
<FlatList
data={DATA}
maxToRenderPerBatch={10}
/>
Aantal items dat per batch wordt gerenderd. Lagere waarde = soepeler scrollen.
Veelgemaakte Fouten
1. Vergeten keyExtractor
// FOUT
<FlatList data={DATA} renderItem={...} />
// GOED
<FlatList
data={DATA}
keyExtractor={(item) => item.id}
renderItem={...}
/>
2. .map() gebruiken in plaats van FlatList
// FOUT - slecht voor performance
<ScrollView>
{DATA.map(item => <Item key={item.id} />)}
</ScrollView>
// GOED
<FlatList data={DATA} renderItem={...} />
Samenvatting
FlatList
Efficiënt lijsten renderen
keyExtractor
Unieke key voor elk item
Pull to Refresh
refreshing + onRefresh
SectionList
Lijsten met secties
Je hebt nu geleerd:
- FlatList gebruiken voor efficiënte lijsten
- Data, keyExtractor en renderItem props
- Pull to refresh implementeren
- SectionList voor lijsten met headers
- Performance optimalisaties toepassen
- Veelgemaakte fouten vermijden