Fetch a asynchronní kód
Asynchronní kód je kód, který se spustí v pozadí a nečekáme na jeho dokončení, ale nastavíme si tzv. callback funkci, která se spustí po dokončení daného kódu a data zpracuje ve správný čas.
Např. Fetch je funkce, která umožňuje načítat data z URL adresy, čekáme tedy na doručení dat a poté data zpracujeme a zobrazíme.
🔌 Práce s API
Máme připravený JSON server, který nám simuluje API a posílá data.
Teď se podíváme, jak tato data načíst pomocí fetch a zobrazit je v naší aplikaci.
Stavy aplikace při načítání dat
Stav aplikace je stav, ve kterém se aplikace nachází. Při načítání dat z API můžeme mít několik stavů:
Stav je potřeba zpracovat a zobrazit uživateli, aby věděl, co se děje.
Načítání dat je ukázka zpracování takových stavů.
- nahrávání - aplikace čeká na doručení dat, chceme zobrazit uživateli, že se načítají data.
- chyba - aplikace nemůže načíst data, chceme zobrazit uživateli, že se stala chyba a popsat co se stalo (nebo taky nechceme 😃) a jak ji napravit.
- úspěch - aplikace načetla data, takže je můžeme zobrazit uživateli.
Základní API služba:
// services/api.js
const API_BASE_URL = 'http://localhost:3001';
export const fetchData = async (setLoading, setError, setData) => {
try {
const response = await fetch(`${API_BASE_URL}/data`);
if (!response.ok) {
throw new Error('Nepodařilo se načíst data');
}
return await response.json();
} catch (error) {
console.error('Chyba při načítání:', error);
throw error;
}
}
Použití fetch v komponentě:
V komponentě musíme myslet na různé stavy - např. načítání, chyba.
// App.jsx
import React, { useState, useEffect } from 'react';
import { fetchData } from './services/api';
const MyCard = () => {
const [data, setData] = useState({});
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetchData(setIsLoading, setError, setData);
}, []);
if (loading) {
return <LoadingSpinner />;
}
if (error) {
return <ErrorMessage message={error} onRetry={loadData} />;
}
return <>
<h1>{data.name}</h1>
<p>{data.website}</p>
</>
};
export default App;
🚀 Tipy a triky
Environment proměnné:
// .env
REACT_APP_API_URL=http://localhost:3001
// services/api.js
const API_BASE_URL = process.env.REACT_APP_API_URL || 'http://localhost:3001';
Fetch retry:
Při načítání dat může dojít k chybě (např. špatné připojení k internetu). Můžeme tedy implementovat retry logiku, která se pokusí načíst data z
const fetchWithRetry = async (url, options = {}, retries = 3) => {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (response.ok){
return response;
};
} catch (error) {
if (i === retries - 1) throw error;
// Čekáme před dalším pokusem
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
};
🔄 Jak to funguje mezi JS a WEB APIs
Pojďme si hrát
console.log("Hi!");
setTimeout(function timeout() {
console.log("Hello, I'm the timer!");
}, 5000);
fetch('example.com')
.then((response) => {
console.log(response);
return response.text();
})
.then((data) => {
console.log(data);
return data;
})
console.log("Everything done. Good job.");
Co teda reálně dělá zavolání fetch
- zavolá WEB API, poprosí o data z URL adresy
- WEB API pošle požadavek na síť a čeká na odpověď
- Ve chvíli, kdy WEB API obdrží odpověď, zavolá callback funkci, která se spustí po dokončení načítání dat
- callback funkce zpracuje data a zobrazí je (v tomto případě v konzoli)
- callback funkce vrátí data
- data jsou zobrazena v prohlížeči