Zróbmy dziś krótki przykład komunikacji z API. Wykorzystanie API JSON jest podstawowym elementem programowania gdzie backend jest oddzielony od frontu, dlatego omówimy poszczególne elementy tego zagadnienia. Skupimy się na sposobie pobierania danych z API JSON za pomocą metody fetch()
i przedstawimy przykładową implementację aplikacji, która pozwoli użytkownikowi wprowadzić nazwę miasta, dla którego chce zobaczyć prognozę pogody.
Skorzystamy z gotowego darmowego API pogodowego na stronie https://www.weatherapi.com/. Aby wykonać prostą aplikację załóż konto na tym portalu aby uzyskać klucz autoryzacyjny.
Na w/w portalu można sprawdzić odpowiedź dla przykładowego miasta , powinna ona wygladać tak :
HEADER
{
"Transfer-Encoding": "chunked",
"Connection": "keep-alive",
"Vary": "Accept-Encoding",
"CDN-PullZone": "93447",
"CDN-Uid": "8fa3a04a-75d9-4707-8056-b7b33c8ac7fe",
"CDN-RequestCountryCode": "GB",
"CDN-ProxyVer": "1.03",
"CDN-RequestPullSuccess": "True",
"CDN-RequestPullCode": "200",
"CDN-CachedAt": "02/28/2023 13:29:25",
"CDN-EdgeStorageId": "1073",
"CDN-Status": "200",
"CDN-RequestId": "51f3ee27a368a0c5b5081c71969a29a1",
"CDN-Cache": "EXPIRED",
"Cache-Control": "public, max-age=180",
"Content-Type": "application/json",
"Date": "Tue, 28 Feb 2023 13:29:25 GMT",
"Server": "BunnyCDN-FR1-946"
}
RESPONSE BODY
{
"location": {
"name": "London",
"region": "City of London, Greater London",
"country": "United Kingdom",
"lat": 51.52,
"lon": -0.11,
"tz_id": "Europe/London",
"localtime_epoch": 1677590965,
"localtime": "2023-02-28 13:29"
},
"current": {
"last_updated_epoch": 1677590100,
"last_updated": "2023-02-28 13:15",
"temp_c": 7.0,
"temp_f": 44.6,
"is_day": 0,
"condition": {
"text": "Overcast",
"icon": "//cdn.weatherapi.com/weather/64x64/night/122.png",
"code": 1009
},
"wind_mph": 8.1,
"wind_kph": 13.0,
"wind_degree": 30,
"wind_dir": "NNE",
"pressure_mb": 1032.0,
"pressure_in": 30.47,
"precip_mm": 0.0,
"precip_in": 0.0,
"humidity": 76,
"cloud": 100,
"feelslike_c": 5.0,
"feelslike_f": 40.9,
"vis_km": 10.0,
"vis_miles": 6.0,
"uv": 1.0,
"gust_mph": 10.1,
"gust_kph": 16.2
}
}
Gdy już posiadasz klucz utwórz nową aplikację w react i stwórz komponent Weather. Komponent będzie najpierw pobierał dane pogodowe z API.
W tym celu użyjemy hooka useState
do przechowywania danych i hooka useEffect
do pobierania danych z API.
Kod wyglądałby mniej więcej tak:
// plik weather.js
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
function Weather() {
const [weatherData, setWeatherData] = useState(null);
const apiKey = "TU_WPROWADŹ_SWOJ_KLUCZ_API";
const location = "London;
useEffect(() => {
fetch(`https://api.weatherapi.com/v1/current.json?key=${apiKey}&q=${location}`)
.then((response) => response.json())
.then((data) => setWeatherData(data));
}, [apiKey, location]);
if (!weatherData) {
return <div>Loading...</div>;
}
return (
<div>
<h1>Pogoda</h1>
<h1>{weatherData.location.name}</h1>
<p>{weatherData.location.region}, {weatherData.location.country}</p>
<p>{weatherData.current.temp_c}°C</p>
<p>{weatherData.current.condition.text}</p>
<img src={weatherData.current.condition.icon} alt={weatherData.current.condition.text} />
</div>
);
}
export default Weather;
W powyższym kodzie użyliśmy hooka useState
do przechowywania danych z API. useEffect
używamy do pobierania danych po załadowaniu komponentu. Zmienna apiKey
zawiera klucz API, a location
to miejsce, dla którego chcemy pobrać dane pogodowe, domyślnie wstawiliśmy wartość "London".
Jeśli weatherData
jest puste, wyświetlamy "Loading...". W przeciwnym razie wyświetlamy dane, które pobraliśmy z API.
W tym przypadku wyświetlamy nazwę miejscowości, region i kraj, temperaturę w stopniach Celsiusza, tekstowe podsumowanie warunków pogodowych oraz ikonę odpowiadającą tym warunkom.
Oczywiście możemy dodać więcej danych pogodowych i stylów do naszej aplikacji, ale to daje podstawowy przykład, jak wykorzystać dane pogodowe w React.
Przyjrzyjmy się jeszcze działaniu funkcji useEffect oraz fetch().useEffect
to hook w React, który pozwala na wykonywanie efektów ubocznych w komponencie funkcyjnym, takich jak pobieranie danych z API czy manipulowanie drzewem DOM. Działa on na zasadzie "subskrypcji" na pewne zmiany, dzięki czemu może reagować na nie i wywoływać określone akcje.
Funkcja fetch()
z kolei jest wbudowaną funkcją w przeglądarkę internetową, która pozwala na pobieranie danych z API za pomocą protokołu HTTP. Funkcja ta zwraca odpowiedź, która może być rozwiązana na obiekt odpowiedzi z serwera. Po otrzymaniu odpowiedzi, można wywołać funkcje do przetworzenia danych, takie jak json()
, text()
, blob()
lub arrayBuffer()
.
W praktyce, kiedy chcemy pobrać dane z API, używamy funkcji fetch()
wewnątrz funkcji useEffect()
, która zostanie wywołana przy każdej zmianie stanu komponentu. Dzięki temu możemy zaktualizować stan komponentu na podstawie pobranych danych lub wywołać inną funkcję w celu ich wykorzystania.
Teraz wykonajmy drobną modyfikację umożliwiającą użytkownikowi wpisanie miejscowości aby dla niej określić pogodę . Dodamy okno tekstowe do wpisania miejscowości oraz dodamy kolejny stan za pomocą hooka 'useState'. Dodamy także funkcję obsługującą wywołanie requestu do API z nowo podaną miejscowością. Docelowy kod powinien wyglądać nastepująco :
// plik weather.js
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
function Weather() {
const [weatherData, setWeatherData] = useState(null);
const apiKey = "TU_WPROWADŹ_SWOJ_KLUCZ_API";
const [location, setLocation] = useState("London");
useEffect(() => {
fetch(`https://api.weatherapi.com/v1/current.json?key=${apiKey}&q=${location}`)
.then((response) => response.json())
.then((data) => setWeatherData(data));
}, [apiKey, location]);
function handleSubmit(event) {
event.preventDefault();
const form = event.target;
const input = form.elements["location"];
setLocation(input.value);
}
if (!weatherData) {
return <div>Loading...</div>;
}
return (
<div>
<h1>Pogoda</h1>
<Link to="/">Home</Link>
<form onSubmit={handleSubmit}>
<label>
Podaj miasto:
<input type="text" name="location" defaultValue={location} />
</label>
<button type="submit">Go</button>
</form>
<h1>{weatherData.location.name}</h1>
<p>{weatherData.location.region}, {weatherData.location.country}</p>
<p>{weatherData.current.temp_c}°C</p>
<p>{weatherData.current.condition.text}</p>
<img src={weatherData.current.condition.icon} alt={weatherData.current.condition.text} />
</div>
);
}
export default Weather;
W powyższym kodzie dodaliśmy stan location
, który przechowuje wartość wpisaną przez użytkownika. Wykorzystujemy tę wartość w zapytaniu do API, aby pobrać dane dla wybranej lokalizacji.
Dodaliśmy również funkcję handleSubmit
, która jest wywoływana, gdy użytkownik naciśnie przycisk "Go". Ta funkcja pobiera wartość z pola tekstowego i ustawia ją jako wartość location
.
W formularzu dodaliśmy pole tekstowe do wpisania nazwy miejscowości, a także przycisk "Go", który wywołuje funkcję handleSubmit
.
W ten sposób umożliwiamy użytkownikowi wybór miejsca, dla którego chce wyświetlić informacje pogodowe.