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

Lógica Compartilhada entre Web e Mobile

Os componentes EventList no web e EventListScreen no mobile têm algo em comum: ambos fazem fetch para /api/events, armazenam o resultado em state, tratam loading e erro. A lógica de UI é diferente (<article> vs <View>, CSS vs StyleSheet), mas a lógica de dados é idêntica.

Podemos extrair essa lógica num custom hook. No projeto mobile, crie src/useEvents.ts:

Arquivo: mobile/src/useEvents.ts
import { useState, useEffect } from "react";
import { Event } from "./types";

export function useEvents(baseUrl: string) {
  const [events, setEvents] = useState<Event[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    fetch(`${baseUrl}/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));
  }, [baseUrl]);

  return { events, loading, error };
}

Código 8-8: Hook que encapsula o fetch de eventos.

O EventListScreen fica mais enxuto:

import { useEvents } from "./useEvents";
import { API_BASE_URL } from "./config";

export default function EventListScreen() {
  const { events, loading, error } = useEvents(API_BASE_URL);

  if (loading) { /* ... */ }
  if (error) { /* ... */ }

  return (
    <FlatList
      data={events}
      keyExtractor={(item) => String(item.id)}
      renderItem={({ item }) => (/* ... */)}
    />
  );
}

O mesmo hook funciona no projeto web — basta copiar useEvents.ts para web/src/ e chamar useEvents("") (string vazia, porque no web o fetch usa URLs relativas via proxy). A lógica de dados vive num lugar só; cada plataforma cuida apenas da sua interface.

Esse é o nível de compartilhamento que faz sentido agora: um hook copiado entre dois projetos. Quando o TamoJunto crescer e o número de hooks compartilhados justificar a complexidade, podemos extrair um pacote shared/ no monorepo.