A feladathoz az https://ergast.com/mrd/ weboldal publikus api-jait fogjuk használni. A weboldalon megtalálható az összes futam adata, 1950-2024-ig.
Előzmény: megnéztük korábban, hogy js segítségével hogyan lehet lekérdezni és megjeleníteni adatokat api segítségével. Ebben a reactos példában ugyanezt fogjuk megoldani.
Készítsünk egy új react alkalmazást! (create vite@latest … korábbi tutorialban benne volt! Plussz a routingot is telepíteni kell: npm install react-router-dom)
Az adott év futamainak adatait a Home.jsx -ben található Home komponens fogja megjeleníteni, a konkrét futam eredményeit pedig Results.jsx -ben található Results komponens. Természetesen lehetett volna akár egy fájlba is írni, de így legalább a routingot is gyakoroljuk.
A Main.jsx tartalmán nem szükséges változtatni.
1 2 3 4 5 6 7 8 9 10 |
import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App.jsx' createRoot(document.getElementById('root')).render( <StrictMode> <App /> </StrictMode>, ) |
Az App.jsx -be importáljuk a Home és a Results tartalmát. Az App.jsx-ben adjuk meg a hivatkozásokat, a BrowserRouter segítségével. A Results komponens elérési útja /results lesz, a Home komponens elérési útvonala pedig a /, azaz a gyökér.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import React, { useEffect, useState } from "react"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import Home from "./Home"; import Results from "./Results"; import './App.css' function App() { const [count, setCount] = useState(0) return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/results/:season/:round" element={<Results />} /> </Routes> </BrowserRouter> ) } export default App |
Home.jsx Nézzük meg az adott év futamainak lekérdezését, és megjelenítését! Nézzünk bele az api által visszaadott json-ba!

Az api-ban megadjuk a csúszkán kiválasztott évszámot.
https://ergast.com/api/f1/${season}.json
Ha másik évszámot választunk, akkor frissülni fognak azonnal az adatok. A futamok dátumaiból készítünk hivatkozást, amire kattintva az adott futam eredményeit fogjuk megjeleníteni. Korábban megnéztük a react hivatkozások használatát. Importálni kell a Link osztályt, és látrehozni a hivatkozásokat a results komponensre! Hasonlóan a sima js weboldalhoz, itt is elküldjük az évet, és a szezon sorszámát. Az App.jsx-ben megadott routing alapján a Results komponens elérési útja: /results utána pedig hozzáadjuk a paramétereket, évszámot és a futam sorszámát.
<Link to={/results/${race.season}/${race.round}
}>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
import React, { useEffect, useState } from "react"; import { Link } from "react-router-dom"; function Home() { const [races, setRaces] = useState([]); const [season, setSeason] = useState(2024); // Alapértelmezett év (season) const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // API-lekérdezés adott év alapján useEffect(() => { const fetchRaces = async () => { setLoading(true); setError(null); try { const response = await fetch(`https://ergast.com/api/f1/${season}.json`); if (!response.ok) { throw new Error(`Hiba történt: ${response.status}`); } const data = await response.json(); setRaces(data.MRData.RaceTable.Races); } catch (err) { setError(err.message); } finally { setLoading(false); } }; fetchRaces(); }, [season]); // A szezon változása újraindítja a lekérdezést // Csúszka értékének kezelése const handleSeasonChange = (e) => { setSeason(Number(e.target.value)); }; if (loading) return <p>Betöltés...</p>; if (error) return <p>Hiba: {error}</p>; return ( <div> <h1>{season} F1 futamok</h1> {/* Csúszka az évszám kiválasztásához */} <div> <label htmlFor="season-slider"> Szezon: <strong>{season}</strong> </label> <input id="season-slider" type="range" min="1950" max="2025" value={season} onChange={handleSeasonChange} /> </div> {/* Futamok listája */} <div className="race-list"> {races.length === 0 ? ( <p>Nincs elérhető futam ehhez a szezonhoz.</p> ) : ( races.map((race) => ( <div key={race.round} className="race-item"> <strong>{race.round}. futam: {race.raceName}</strong> <p><i>Pálya neve: {race.Circuit.circuitName}</i></p> <p><i>Ország: {race.Circuit.Location.country}</i></p> <div> <Link to={`/results/${race.season}/${race.round}`}> {race.date} </Link> </div> </div> )) )} </div> </div> ); } export default Home; |
A futamok eredményét a https://ergast.com/api/f1/2000/1/results.json api címen érjük el. Nézzük meg, mit ad vissza! Ebből a json-ból fogjuk kiszedni a pilóták, istállók adatait.

Results.jsx A Results komponens felelős a futamon elért eredmények lekérdezéséért, és megjelenítéséért. Az évszámot és a futam sorszámát a hivatkozásból kapja meg, paraméterként. Gyakorlatilag ugyanúgy működik, mint a sima js weboldalon.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import React, { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; function Results() { const { season, round } = useParams(); const [results, setResults] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchResults = async () => { try { const response = await fetch(`https://ergast.com/api/f1/${season}/${round}/results.json`); if (!response.ok) { throw new Error(`Hiba történt: ${response.status}`); } const data = await response.json(); setResults(data.MRData.RaceTable.Races[0]?.Results || []); } catch (err) { setError(err.message); } finally { setLoading(false); } }; fetchResults(); }, [season, round]); if (loading) return <p>Betöltés...</p>; if (error) return <p>Hiba: {error}</p>; if (results.length === 0) { return <p>Nincs elérhető adat ehhez a futamhoz.</p>; } return ( <div> <h1>Futam Eredmények</h1> <div className="results-list"> {results.map((result) => ( <div key={result.position} className="result-item"> <span className="position">Helyezés: {result.position}</span> <div>Pilóta: {result.Driver.givenName} {result.Driver.familyName}</div> <div>Csapat: {result.Constructor.name}</div> <div>Idő: {result.Time?.time || "N/A"}</div> </div> ))} </div> </div> ); } export default Results; |