Heim  >  Artikel  >  Web-Frontend  >  Erstellen einer Country Finder-Anwendung mit React

Erstellen einer Country Finder-Anwendung mit React

DDD
DDDOriginal
2024-09-13 14:15:261006Durchsuche

Building a Country Finder Application with React

Einführung

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.

Projektübersicht

Die Country Finder-Anwendung bietet eine interaktive Schnittstelle, über die Benutzer Folgendes tun können:

  • Suchen Sie nach Ländern nach Namen.
  • Länder nach Region filtern.
  • Detaillierte Informationen zu jedem Land anzeigen, einschließlich seiner Flagge, Bevölkerung und mehr.

Merkmale

  • Suchleiste: Ermöglicht Benutzern die Suche nach Ländern anhand des Namens.
  • Nach Region filtern: Dropdown-Menü zum Filtern von Ländern nach ihrer Region.
  • Länderdetails: Zeigt detaillierte Informationen zu einem ausgewählten Land an.
  • Themenumschaltung: Wechseln Sie zwischen hellen und dunklen Themen.

Verwendete Technologien

  • React: JavaScript-Bibliothek zum Erstellen von Benutzeroberflächen.
  • REST-Länder-API: Stellt Daten über Länder bereit.
  • CSS: Zum Gestalten der Anwendung.
  • React Router: Zum Navigieren zwischen Seiten und zum Übergeben von Status.

Projektstruktur

Das Projekt ist in mehrere Komponenten gegliedert:

  • App.js: Hauptkomponente, die den Header und das Outlet für das Routing enthält.
  • Header.js: Zeigt den Anwendungstitel und die Schaltfläche zum Umschalten des Themas an.
  • Home.js: Hauptseite mit Such- und Filteroptionen und einer Liste von Ländern.
  • SearchBar.js: Komponente zur Ländersuche.
  • SelectMenu.js: Dropdown-Menü zum Filtern von Ländern nach Region.
  • CountriesList.js: Zeigt eine Liste der Länder basierend auf den Such- und Filterkriterien an.
  • CountryCard.js: Zeigt eine Zusammenfassung jedes Landes an.
  • CountryDetail.js: Zeigt detaillierte Informationen zu einem ausgewählten Land an.
  • CountryDetailShimmer.js: Platzhalter für Länderdetails wird geladen.
  • Error.js: Fehlerbehandlungskomponente für Routen.

Installation

  1. Klonen Sie das Repository:
   git clone https://github.com/abhishekgurjar-in/country-finder.git
   cd country-finder
  1. Abhängigkeiten installieren:
   npm install
  1. Starten Sie den Entwicklungsserver:
   npm start

Verwendung

  1. Nach einem Land suchen: Geben Sie einen Ländernamen in die Suchleiste ein, um die Liste der Länder zu filtern.
  2. Nach Region filtern: Wählen Sie eine Region aus dem Dropdown-Menü aus, um Länder in dieser Region anzuzeigen.
  3. Details anzeigen: Klicken Sie auf eine Länderkarte, um detaillierte Informationen über das Land anzuzeigen.

Code-Erklärung

App.js

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;

Header.js

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>
  )
}

Home.js

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>
  )
}

SearchBar.js

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>
  )
}

SelectMenu.js

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>
  )
}

CountriesList.js

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>
  )
}

CountryDetail.js

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>
  );
}

CountryDetailShimmer.js

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>
  );
}

CountryCard.js

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>
  );
}

CountriesListShimmer.js

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>
  );
}

Live-Demo

Sie können eine Live-Demo der Country Finder-Anwendung ansehen, indem Sie Country Finder Demo besuchen.

Abschluss

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.

Credits

  • Reagieren: Reagieren
  • REST-Länder-API: REST-Länder
  • Font Awesome: Font Awesome

Autor

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn