FlatList Básico
Volver a clases
Principiante

FlatList Básico

120 min
64 vistas

FlatList

¿Por qué FlatList?

typescript
1// ❌ Mal - ScrollView con map (renderiza todo)
2<ScrollView>
3  {items.map(item => <Item key={item.id} data={item} />)}
4</ScrollView>
5
6// ✅ Bien - FlatList (renderiza solo lo visible)
7<FlatList
8  data={items}
9  renderItem={({ item }) => <Item data={item} />}
10  keyExtractor={item => item.id.toString()}
11/>

FlatList Básico

typescript
1import { FlatList, View, Text, StyleSheet } from "react-native";
2
3interface Product {
4  id: number;
5  name: string;
6  price: number;
7}
8
9const PRODUCTS: Product[] = [
10  { id: 1, name: "iPhone 15", price: 999 },
11  { id: 2, name: "AirPods Pro", price: 249 },
12  { id: 3, name: "MacBook Pro", price: 1999 },
13];
14
15function ProductList() {
16  const renderProduct = ({ item }: { item: Product }) => (
17    <View style={styles.productCard}>
18      <Text style={styles.productName}>{item.name}</Text>
19      <Text style={styles.productPrice}>${item.price}</Text>
20    </View>
21  );
22
23  return (
24    <FlatList
25      data={PRODUCTS}
26      renderItem={renderProduct}
27      keyExtractor={(item) => item.id.toString()}
28    />
29  );
30}
31
32const styles = StyleSheet.create({
33  productCard: {
34    padding: 16,
35    backgroundColor: "white",
36    marginBottom: 8,
37    marginHorizontal: 16,
38    borderRadius: 8,
39  },
40  productName: {
41    fontSize: 18,
42    fontWeight: "600",
43    marginBottom: 4,
44  },
45  productPrice: {
46    fontSize: 16,
47    color: "#007AFF",
48  },
49});

Props Importantes de FlatList

typescript
1<FlatList
2  data={items}
3  renderItem={renderItem}
4  keyExtractor={(item) => item.id}
5  // Separadores
6  ItemSeparatorComponent={() => (
7    <View style={{ height: 1, backgroundColor: "#eee" }} />
8  )}
9  // Estados vacíos
10  ListEmptyComponent={<Text style={styles.empty}>No hay items</Text>}
11  // Header y Footer
12  ListHeaderComponent={<Text style={styles.header}>Lista de Productos</Text>}
13  ListFooterComponent={<Text style={styles.footer}>Fin de la lista</Text>}
14  // Estilos
15  contentContainerStyle={styles.contentContainer}
16  // Scroll
17  showsVerticalScrollIndicator={false}
18  // Refresh
19  refreshing={refreshing}
20  onRefresh={handleRefresh}
21  // Infinite scroll
22  onEndReached={loadMore}
23  onEndReachedThreshold={0.5}
24/>

Pull to Refresh

typescript
1import { useState } from "react";
2import { FlatList, RefreshControl } from "react-native";
3
4function ProductList() {
5  const [products, setProducts] = useState(INITIAL_PRODUCTS);
6  const [refreshing, setRefreshing] = useState(false);
7
8  const onRefresh = async () => {
9    setRefreshing(true);
10
11    // Simular fetch
12    await new Promise((resolve) => setTimeout(resolve, 2000));
13
14    // Actualizar datos
15    setProducts([...INITIAL_PRODUCTS]);
16    setRefreshing(false);
17  };
18
19  return (
20    <FlatList
21      data={products}
22      renderItem={renderProduct}
23      keyExtractor={(item) => item.id.toString()}
24      refreshControl={
25        <RefreshControl
26          refreshing={refreshing}
27          onRefresh={onRefresh}
28          tintColor="#007AFF"
29        />
30      }
31    />
32  );
33}