Lista de Eventos com FlatList
No React para web, renderizar uma lista é events.map(...). No React Native,
listas grandes usam o componente FlatList. A razão: numa lista com 500 itens,
o map renderiza todos os 500 de uma vez. A FlatList renderiza apenas os
itens visíveis na tela e recicla as views conforme o usuário rola — o equivalente
a RecyclerView no Android ou UICollectionView no iOS.
Com 12 eventos, a diferença de performance é imperceptível. Mas o hábito de
usar FlatList desde o início evita a refatoração quando a lista crescer.
Crie src/EventListScreen.tsx:
import { useState, useEffect } from "react";
import {
View,
Text,
FlatList,
StyleSheet,
ActivityIndicator,
} from "react-native";
import { Event } from "./types";
import { API_BASE_URL } from "./config";
export default function EventListScreen() {
const [events, setEvents] = useState<Event[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
fetch(`${API_BASE_URL}/api/events`)
.then((res) => {
if (!res.ok) throw new Error(`Erro ${res.status}`);
return res.json();
})
.then((data) => setEvents(data))
.catch((err) => setError(err.message))
.finally(() => setLoading(false));
}, []);
if (loading) {
return (
<View style={styles.center}>
<ActivityIndicator size="large" color="#3182ce" />
</View>
);
}
if (error) {
return (
<View style={styles.center}>
<Text style={styles.error}>{error}</Text>
</View>
);
}
return (
<FlatList
data={events}
keyExtractor={(item) => String(item.id)}
contentContainerStyle={styles.list}
renderItem={({ item }) => (
<View style={styles.card}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.date}>
{new Date(item.date).toLocaleString("pt-BR", {
dateStyle: "short",
timeStyle: "short",
})}
</Text>
<Text style={styles.description}>{item.description}</Text>
<Text style={styles.location}>📍 {item.location}</Text>
<Text style={styles.info}>
Vagas: {item.capacity} · {item.organizer_name}
</Text>
</View>
)}
/>
);
}
const styles = StyleSheet.create({
center: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
list: {
padding: 16,
},
card: {
backgroundColor: "#fff",
borderRadius: 8,
padding: 16,
marginBottom: 12,
borderWidth: 1,
borderColor: "#e2e8f0",
},
title: {
fontSize: 18,
fontWeight: "600",
marginBottom: 4,
},
date: {
color: "#718096",
fontSize: 14,
marginBottom: 8,
},
description: {
fontSize: 15,
marginBottom: 4,
},
location: {
fontSize: 14,
marginBottom: 4,
},
info: {
fontSize: 14,
color: "#4a5568",
},
error: {
color: "#e53e3e",
fontSize: 16,
},
});
Código 8-3: Lista de eventos usando FlatList.
A FlatList recebe três props obrigatórios:
data— o array de itens.keyExtractor— uma função que retorna um identificador único para cada item (equivalente aokeyno React web).renderItem— uma função que recebe um item e retorna o componente a ser renderizado.
Estilos no React Native
CSS não existe no React Native. Em vez de seletores e cascata, cada componente
recebe estilos via objetos JavaScript criados com StyleSheet.create. As
propriedades são camelCase (backgroundColor em vez de background-color) e os
valores são números (pixels) ou strings.
Não existe display: block nem display: inline. Todo contêiner é flex por
padrão — flexDirection começa como "column" (diferente da web, onde o
padrão é "row"). Isso faz sentido: telas de celular são verticais, e a
maioria dos layouts mobile é uma coluna de elementos empilhados.