
FlatList
¿Por qué FlatList?
typescript1// ❌ 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
typescript1import { 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
typescript1<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
typescript1import { 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}