In diesem Blogbeitrag erfahren Sie, wie Sie mit React eine Country Finder-Anwendung erstellen. Mit dieser Anwendung können Benutzer nach Ländern suchen, sie nach Region filtern und detaillierte Informationen zu jedem Land anzeigen. Wir werden die Hooks und den Kontext von React nutzen, um Status und Themen zu verwalten, und wir werden die REST-Länder-API integrieren, um Länderdaten abzurufen.
Die Country Finder-Anwendung bietet eine interaktive Schnittstelle, über die Benutzer Folgendes tun können:
Das Projekt ist in mehrere Komponenten gegliedert:
git clone https://github.com/abhishekgurjar-in/country-finder.git cd country-finder
npm install
npm start
Die App-Komponente umschließt die Header- und Outlet-Komponenten in einem ThemeProvider und verwaltet den Theme-Status in der gesamten Anwendung.
import Header from "./components/Header"; import { Outlet } from "react-router-dom"; import "./App.css"; import { ThemeProvider } from "./contexts/ThemeContext"; const App = () => { return ( <ThemeProvider> <Header /> <Outlet /> </ThemeProvider> ); }; export default App;
Mit der Header-Komponente können Benutzer zwischen hellen und dunklen Themen wechseln und den Anwendungstitel anzeigen.
import { useTheme } from "../hooks/useTheme" export default function Header() { const [isDark, setIsDark] = useTheme(); return ( <header className={`header-container ${isDark ? 'dark' : ''}`}> <div className="header-content"> <h2 className="title"> <a href="/">Country Finder</a> </h2> <p className="theme-changer" onClick={() => { setIsDark(!isDark); localStorage.setItem('isDarkMode', !isDark); }}> <i className={`fa-solid fa-${isDark ? 'sun' : 'moon'}`} /> {isDark ? 'Light' : 'Dark'} Mode </p> </div> </header> ) }
Die Home-Komponente enthält die Suchleiste, das Filtermenü und listet die Länder basierend auf den Such- und Filterkriterien auf.
import React, { useState } from 'react'; import SearchBar from './SearchBar'; import SelectMenu from './SelectMenu'; import CountriesList from './CountriesList'; import { useTheme } from '../hooks/useTheme'; export default function Home() { const [query, setQuery] = useState(''); const [isDark] = useTheme(); return ( <main className={`${isDark ? 'dark' : ''}`}> <div className="search-filter-container"> <SearchBar setQuery={setQuery} /> <SelectMenu setQuery={setQuery} /> </div> <CountriesList query={query} /> </main> ) }
Die SearchBar-Komponente verarbeitet Benutzereingaben für die Suche nach Ländern.
import React from 'react'; export default function SearchBar({ setQuery }) { return ( <div className="search-container"> <i className="fa-solid fa-magnifying-glass"></i> <input onChange={(e) => setQuery(e.target.value.toLowerCase())} type="text" placeholder="Search for a country..." /> </div> ) }
Die SelectMenu-Komponente bietet ein Dropdown-Menü zum Filtern von Ländern nach Region.
import React from 'react'; export default function SelectMenu({ setQuery }) { return ( <select className="filter-by-region" onChange={(e) => setQuery(e.target.value.toLowerCase())}> <option hidden>Filter by Region</option> <option value="Africa">Africa</option> <option value="Americas">Americas</option> <option value="Asia">Asia</option> <option value="Europe">Europe</option> <option value="Oceania">Oceania</option> </select> ) }
Die CountriesList-Komponente ruft eine Liste der Länder ab und zeigt sie an.
import React, { useEffect, useState } from 'react'; import CountryCard from './CountryCard'; import CountriesListShimmer from './CountriesListShimmer'; export default function CountriesList({ query }) { const [countriesData, setCountriesData] = useState([]); useEffect(() => { fetch('https://restcountries.com/v3.1/all') .then((res) => res.json()) .then((data) => { setCountriesData(data); }); }, []); if (!countriesData.length) { return <CountriesListShimmer />; } return ( <div className="countries-container"> {countriesData .filter((country) => country.name.common.toLowerCase().includes(query) || country.region.toLowerCase().includes(query) ) .map((country) => ( <CountryCard key={country.name.common} name={country.name.common} flag={country.flags.svg} population={country.population} region={country.region} capital={country.capital?.[0]} data={country} /> ))} </div> ) }
Die CountryDetail-Komponente ruft detaillierte Informationen zu einem ausgewählten Land ab und zeigt sie an.
import React, { useEffect, useState } from 'react'; import { Link, useLocation, useParams } from 'react-router-dom'; import { useTheme } from '../hooks/useTheme'; import CountryDetailShimmer from './CountryDetailShimmer'; import './CountryDetail.css'; export default function CountryDetail() { const [isDark] = useTheme(); const params = useParams(); const { state } = useLocation(); const countryName = params.country; const [countryData, setCountryData] = useState(null); const [notFound, setNotFound] = useState(false); function updateCountryData(data) { setCountryData({ name: data.name.common || data.name, nativeName: Object.values(data.name.nativeName || {})[0]?.common, population: data.population, region: data.region, subregion: data.subregion, capital: data.capital, flag: data.flags.svg, tld: data.tld, languages: Object.values(data.languages || {}).join(', '), currencies: Object.values(data.currencies || {}) .map((currency) => currency.name) .join(', '), borders: [], }); if (!data.borders) { data.borders = []; } Promise.all( data.borders.map((border) => fetch(`https://restcountries.com/v3.1/alpha/${border}`) .then((res) => res.json()) .then(([borderCountry]) => borderCountry.name.common) ) ).then((borders) => { setTimeout(() => setCountryData((prevState) => ({ ...prevState, borders })) ); }); } useEffect(() => { if (state) { updateCountryData(state); return; } fetch(`https://restcountries.com/v3.1/name/${countryName}?fullText=true`) .then((res) => res.json()) .then(([data]) => { if (!data) { setNotFound(true); } else { updateCountryData(data); } }) .catch(() => setNotFound(true)); }, [countryName, state]); if (notFound) { return ( <div className={`error-container ${isDark ? 'dark' : ''}`}> <h3>Country not found</h3> <Link to="/">Back to home</Link> </div> ); } if (!countryData) { return <CountryDetailShimmer />; } return ( <div className={`country-detail-container ${isDark ? 'dark' : ''}`}> <Link to="/" className="back-button"> <i className="fa-solid fa-arrow-left" /> Back </Link> <div className="country-detail-content"> <img src={countryData.flag} alt={`${countryData.name} flag`} /> <div className="country-detail-info"> <h1>{countryData.name}</h1> <div className="details"> <p><strong>Native Name:</strong> {countryData.nativeName}</p> <p><strong>Population:</strong> {countryData.population}</p> <p><strong>Region:</strong> {countryData.region}</p> <p><strong>Subregion:</strong> {countryData.subregion}</p> <p><strong>Capital:</strong> {countryData.capital}</p> <p><strong>Top Level Domain:</strong> {countryData.tld}</p> <p><strong>Languages:</strong> {countryData.languages}</p> <p><strong>Currencies:</strong> {countryData.currencies}</p> <p><strong>Border Countries:</strong> {countryData.borders.join(', ') || 'None'}</p> </div> </div> </div> </div> ); }
Die CountryDetailShimmer-Komponente zeigt beim Abrufen von Länderdetails einen Ladeplatzhalter an.
import React from 'react'; export default function CountryDetailShimmer() { return ( <div className="country-detail-shimmer"> <div className="shimmer-img"></div> <div className="shimmer-info"> <div className="shimmer-line name"></div> <div className="shimmer-line"></div> <div className="shimmer-line"></div> <div className="shimmer-line"></div> <div className="shimmer-line"></div> </div> </div> ); }
Die CountryCard-Komponente zeigt einen kurzen Überblick über jedes Land.
import React from 'react'; import { Link } from 'react-router-dom'; export default function CountryCard({ name, flag, population, region, capital, data }) { return ( <div className="country-card"> <img src={flag} alt={`${name} flag`} /> <h3>{name}</h3> <p><strong>Population:</strong> {population}</p> <p><strong>Region:</strong> {region}</p> <p><strong>Capital:</strong> {capital}</p> <Link to={`/country/${name}`} state={data}> <button>More Details</button> </Link> </div> ); }
Die CountriesListShimmer-Komponente zeigt beim Abrufen der Länderliste einen Ladeplatzhalter an.
import React from 'react'; export default function CountriesListShimmer() { return ( <div className="countries-list-shimmer"> {Array.from({ length: 10 }).map((_, index) => ( <div key={index} className="shimmer-card"></div> ))} </div> ); }
Sie können eine Live-Demo der Country Finder-Anwendung ansehen, indem Sie Country Finder Demo besuchen.
In diesem Projekt haben wir mit React eine Country Finder-Anwendung erstellt, mit der Benutzer nach Ländern suchen, sie nach Region filtern und detaillierte Informationen anzeigen können. Wir haben die REST-Länder-API integriert und die Hooks und den Kontext von React verwendet, um Status und Theming zu verwalten.
Abhishek Gurjar ist ein engagierter Webentwickler, der sich mit der Entwicklung praktischer und funktionaler Webanwendungen beschäftigt. Schauen Sie sich weitere seiner Projekte auf GitHub an.
Das obige ist der detaillierte Inhalt vonErstellen einer Country Finder-Anwendung mit React. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!