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 data
  • keyExtractor - Functie die unieke key returned
  • renderItem - 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 wordt
  • onRefresh - 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 headers
  • renderItem - 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