Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

Arquivo: mobile/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 ao key no 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.