RN Lez 23: fetch GET
Docs: Network
Obiettivi
Section titled “Obiettivi”- Fare chiamate GET con fetch
- Gestire loading, dati, errori
- Mostrare dati da API in FlatList
1. useEffect + fetch
Section titled “1. useEffect + fetch”Pattern standard per caricare dati all’avvio:
const [dati, setDati] = useState<any[]>([]);const [loading, setLoading] = useState(true);const [errore, setErrore] = useState<string | null>(null);
useEffect(() => { const carica = async () => { try { const res = await fetch('https://api.esempio.com/dati'); if (!res.ok) throw new Error(`HTTP ${res.status}`); const json = await res.json(); setDati(json); } catch (err) { setErrore((err as Error).message); } finally { setLoading(false); } }; carica();}, []);2. Stati: loading + errore + dati
Section titled “2. Stati: loading + errore + dati”if (loading) { return ( <View style={styles.center}> <ActivityIndicator size="large" color="#3498db" /> <Text style={{ marginTop: 10, color: 'grey' }}>Caricamento...</Text> </View> );}
if (errore) { return ( <View style={styles.center}> <Text style={{ color: 'red', fontSize: 18 }}>❌ {errore}</Text> <Button title="Riprova" onPress={ricarica} /> </View> );}
return <FlatList data={dati} renderItem={renderItem} />;3. Esempio: Lista post da API
Section titled “3. Esempio: Lista post da API”import { useState, useEffect } from 'react';import { View, Text, FlatList, ActivityIndicator, Button, StyleSheet } from 'react-native';
type Post = { id: number; title: string; body: string;};
export default function App() { const [posts, setPosts] = useState<Post[]>([]); const [loading, setLoading] = useState(true); const [errore, setErrore] = useState<string | null>(null);
const carica = async () => { setLoading(true); setErrore(null); try { const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=10'); if (!res.ok) throw new Error('Errore caricamento'); setPosts(await res.json()); } catch (err) { setErrore((err as Error).message); } finally { setLoading(false); } };
useEffect(() => { carica(); }, []);
if (loading) return ( <View style={styles.center}><ActivityIndicator size="large" /><Text>Caricamento...</Text></View> );
if (errore) return ( <View style={styles.center}> <Text style={{ color: 'red', fontSize: 18 }}>❌ {errore}</Text> <Button title="Riprova" onPress={carica} /> </View> );
return ( <View style={styles.container}> <Text style={styles.titolo}>📰 Posts</Text> <FlatList data={posts} renderItem={({ item }) => ( <View style={styles.card}> <Text style={styles.id}>#{item.id}</Text> <Text style={styles.title}>{item.title}</Text> </View> )} keyExtractor={item => item.id.toString()} /> </View> );}4. API pubbliche gratuite
Section titled “4. API pubbliche gratuite”| API | URL | Cosa restituisce |
|---|---|---|
| JSONPlaceholder | jsonplaceholder.typicode.com/posts | Posts, users |
| JSONPlaceholder users | jsonplaceholder.typicode.com/users | Utenti |
| Rick & Morty | rickandmortyapi.com/api/character | Personaggi |
| Open-Meteo | api.open-meteo.com/v1/forecast | Meteo (no API key) |
5. Tabella riassuntiva
Section titled “5. Tabella riassuntiva”| Passaggio | Codice |
|---|---|
| Chiamata | const res = await fetch(url) |
| JSON | const data = await res.json() |
| Controllo errori | if (!res.ok) throw Error() |
| Loading | useState(true) → set a false dopo |
| Errore | useState(null) → set messaggio |
6. Esercizio
Section titled “6. Esercizio”🎯 “Elenco utenti”
Section titled “🎯 “Elenco utenti””Crea un’app che carica utenti da https://jsonplaceholder.typicode.com/users e mostra:
- Nome (grassetto)
- Email (grigio)
- Telefono
- ActivityIndicator durante caricamento
- Gestione errore se fallisce
- Bottone “Riprova” in caso di errore