In vielen Webanwendungen begegnen wir häufig Formularen, bei denen die Auswahl einer Option in einem Dropdown ein neues Set von Optionen in einem anderen freischaltet. Diese miteinander verbundenen Dropdowns, die häufig als abhängige oder kaskadierende Dropdowns bezeichnet werden, spielen eine entscheidende Rolle dabei, ein nahtloses und intuitives Ausfüllen von Formularen zu ermöglichen.

Ob es darum geht, ein Land auszuwählen, um die entsprechenden Bundesstaaten anzuzeigen, oder eine Produktkategorie auszuwählen, um spezifische Artikel anzuzeigen, diese Dropdowns vereinfachen komplexe Entscheidungen für alle. Für Entwickler ist die Implementierung von abhängigen Dropdowns eine praktische Herausforderung, die Logik, Benutzerfreundlichkeit und die dynamische Verarbeitung von Daten kombiniert.

In diesem Tutorial lernen Sie, wie Sie diesen Typ von Dropdown in Ihrer React-Anwendung implementieren.

Inhaltsverzeichnis

Was ist eine abhängige Dropdown-Liste?

Eine abhängige Dropdown-Liste ist ein UI-Element, bei dem die verfügbaren Optionen in einer Dropdown-Liste durch die Auswahl in einer anderen Dropdown-Liste bestimmt werden. Zum Beispiel, betrachten Sie ein Szenario, in dem Sie zwei Dropdown-Listen haben:

  1. Länder-Dropdown-Liste: Der Benutzer wählt ein Land aus.

  2. Städte-Dropdown-Liste: Basierend auf dem ausgewählten Land wird die Liste der verfügbaren Städte in der zweiten Dropdown-Liste entsprechend gefiltert.

Diese Art der Interaktion ist entscheidend für Formulare, die komplexe, kontextsensitive Dateneingaben erfordern.

Wie funktioniert eine abhängige Dropdown-Liste?

Abhängige Dropdown-Listen funktionieren, indem die Optionen der zweiten Dropdown-Liste dynamisch aktualisiert werden, basierend auf dem Wert, der in der ersten Dropdown-Liste ausgewählt wurde. Diese dynamische Änderung wird in der Regel durchgeführt, indem:

  1. Auf Benutzereingaben hören: Wenn der Benutzer eine Option in der ersten Dropdown-Liste auswählt, löst ein Ereignis (normalerweise onChange) eine Funktion aus, um den Status zu aktualisieren.

  2. Neue Daten abrufen: Dieser aktualisierte Zustand kann verwendet werden, um entweder die vorhandenen Daten zu filtern oder einen API-Aufruf zu machen, um die neue Liste von Optionen abzurufen.

  3. Neue Daten rendern: Das zweite Dropdown wird dann mit den neuen Optionen aktualisiert, die dem Benutzer relevante Auswahlmöglichkeiten bieten.

Schritte zum Erstellen abhängiger Dropdowns in React

Schritt 1: Richten Sie Ihr React-Projekt ein

Wenn Sie neu bei React sind und mitmachen möchten, sehen Sie sich die Vite-Dokumentation an und folgen Sie den Schritten, um Ihr React-Projekt zu erstellen. Wenn Sie fertig sind, kommen Sie hierher zurück und lassen Sie uns weiterbauen.

Wenn Sie bereits ein React-Projekt haben, das Sie verwenden möchten, ist das auch großartig.

Schritt 2: Strukturieren Sie die Komponente

Zur Vereinfachung nehmen wir an, dass wir ein zweistufiges abhängiges Dropdown erstellen, bei dem das erste Dropdown es Ihnen ermöglicht, ein Land auszuwählen, und das zweite Dropdown Städte basierend auf dem ausgewählten Land anzeigt.

Außerdem haben wir im Länder-Dropdown eine weitere Option zum Eingeben eines Landesnamens, der nicht in den Länderoptionen enthalten ist. Der Benutzer kann dann fortfahren und sein Land in ein Texteingabefeld eingeben.

Erstellen Sie zunächst eine neue Datei mit dem Namen DependentDropdown.js oder DependentDropdown.jsx. Definieren Sie in dieser Datei eine funktionale Komponente namens DependentDropdown.

Jetzt werden wir die folgenden Schritte durchgehen, um unseren abhängigen Dropdown aufzubauen:

Deklaration von Variablen zur Speicherung von Daten

Wir müssen statische Daten für die Werte unserer Länder und Städte erstellen:

  // Statische Länderdaten
  const countries = [
    { id: 1, name: 'USA' },
    { id: 2, name: 'Canada' },
    { id: 3, name: 'Other' },
  ];

  // Statische Städtedaten, die den Ländern entsprechen
  const cities = {
    USA: ['New York', 'Los Angeles', 'Chicago'],
    Canada: ['Toronto', 'Vancouver', 'Montreal'],
  };
  • Länder ist ein Array von Objekten. Jedes Objekt hat Eigenschaften von id und name.

  • Städte ist ein Objekt mit Ländernamen als Schlüssel und den Werten als Array von Städten.

Deklaration von Statusvariablen

Für jede Auswahl eines Landes oder einer Stadt möchten wir die ausgewählten Werte verfolgen können. Wir möchten auch die Städte-Option nach einer getroffenen Landauswahl bevölkern können. Dazu müssen wir einige Zustände deklarieren.

Wenn das Konzept des Zustands neu für Sie ist, können Sie meinen Artikel über den Zustand hier lesen.

  const [selectedCountry, setSelectedCountry] = useState('');
  const [availableCities, setAvailableCities] = useState([]);
  const [selectedCity, setSelectedCity] = useState('');
  const [otherCountry, setOtherCountry] = useState('');
  • Der Zustand selectedCountry wird deklariert und sein Anfangswert wird auf einen leeren String gesetzt.

  • Der Zustand availableCities wird deklariert und sein Anfangswert wird auf ein leeres Array gesetzt.

  • Der Zustand selectedCity wird deklariert und sein Anfangswert wird auf einen leeren String gesetzt.

  • Der Zustand otherCountry wird deklariert und sein Anfangswert wird auf einen leeren String gesetzt.

Behandlung von Ereignissen

Im Prozess der Auswahl im Dropdown-Menü möchten wir einige Aktionen durchführen. Ereignisbehandler ermöglichen es uns, dies im Falle eines Ereignisses zu tun, das in diesem Fall das onChange-Ereignis ist.

  const handleCountryChange = (e) => {
    const country = e.target.value;
    setSelectedCountry(country);
    setAvailableCities(cities[country] || []);
    setSelectedCity(''); 
     if (country !== 'Other') {
      setOtherCountry('');
    }
  };

Hier ist, was in der Funktion handleCountryChange passiert:

  • Holt den Wert der ausgewählten Option im Dropdown-Menü (das ausgewählte Land).

  • Die setSelectedCountry aktualisiert die Statusvariable (selectedCountry) mit dem neu ausgewählten Land.

  • cities[country] sucht die Liste der Städte für das ausgewählte Land im cities Objekt.

    • Wenn cities[country] gefunden wird, setzt es diese Liste von Städten als verfügbare Städte.

    • Wenn keine Städte für das ausgewählte Land gefunden werden (cities[country] ist undefined), stellt || [] sicher, dass ein leeres Array ([]) als Fallback verwendet wird, um Fehler beim Versuch, die Städte anzuzeigen, zu verhindern.

  • Wenn der Benutzer die Länderauswahl ändert, setzt die Funktion setSelectedCity die selectedCity auf einen leeren String zurück.

  • Wenn das ausgewählte Land nicht ‚Andere‘ ist, wird der Zustand otherCountry auf einen leeren String zurückgesetzt. Dies stellt sicher, dass, wenn der Benutzer zuvor etwas in die „Andere“ Eingabe eingegeben hat, dieser Text gelöscht wird, sobald er ein anderes Land auswählt (zum Beispiel „USA“ oder „Kanada“).

Für die Auswahl des Landes „Andere“ müssen wir nur den eingegebenen Wert im Eingabefeld verfolgen. Die Funktion setOtherCountry aktualisiert den eingegebenen Wert. Und so wird es gemacht:

  const handleOtherCountryChange = (e) => {
    setOtherCountry(e.target.value);
  };

Bei der Änderung der Städte müssen wir nicht viel tun, da das ausgewählte Land bestimmt, welche Städte angezeigt werden. Alles, was wir tun müssen, ist, die selectedCity auf den Wert der ausgewählten Option im Dropdown zu aktualisieren, was die ausgewählte Stadt ist.

In React übernimmt die Aktualisierungsfunktion die Aktualisierung von Zustandsvariablen, daher behandelt dies in diesem Fall setSelectedCity.

Die Funktion handleCityChange wird sein:

  const handleCityChange = (e) => {
    setSelectedCity(e.target.value);
  };

Rückgabe JSX

Das Komponente DependentDropdown rendert drei Hauptelemente: das Länder-Dropdown, das Städte-Dropdown und das Länder-Texteingabefeld.

Ein Dropdown in HTML ist eine Kombination der Elemente <select> und <option>. Um den Wert der Elemente im Auge zu behalten, werden wir Zustandsvariablen an sie anhängen, damit wir sie kontrollieren können. Dies wird als ‚Elemente kontrollieren‘ bezeichnet, während die Elemente selbst in React als ‚kontrollierte Elemente‘ bezeichnet werden.

Um das Landes-<select>-Element zu kontrollieren, werden wir ihm ein value-Attribut von selectedCountry geben und auch die Funktion handleCountryChange daran anhängen.

     <label htmlFor="country" className='font-bold'>Select Country: </label>
      <select id="country" value={selectedCountry} onChange={handleCountryChange}>
        <option value="">Select a country</option>
        {countries.map((country) => (
          <option key={country.id} value={country.name}>
            {country.name}
          </option>
        ))}
      </select>

Zusätzlich,

  • Innerhalb des <option> mappen wir über das countries-Array und erstellen dynamisch eine <option> für jedes Länderobjekt im Array.

  • Der name jedes Landes wird als Text der Option angezeigt.

  • Der key jeder Option ist auf die id des Landes gesetzt und der value ist auf den name des Landes gesetzt.

  • Der key hilft React, die Liste effizient zu verwalten, wenn sie neu gerendert wird.

Das Dropdown-Menü für Städte wird bedingt basierend auf dem ausgewählten Land gerendert. Wenn die Option ‚Sonstiges‘ gewählt wird, wird ein Texteingabefeld angezeigt, damit der Benutzer das Land angeben kann. Andernfalls, wenn ein gültiges Land ausgewählt wird, wird ein Dropdown-Menü für Städte mit relevanten Optionen angezeigt.

{selectedCountry === 'Other' ? (
        <>
          <label htmlFor="other-country" className='font-bold'>Please specify the country: </label>
          <input
            id="other-country"
            type="text"
            value={otherCountry}
            onChange={handleOtherCountryChange}
            placeholder="Enter country name"
          />
        </>
      ) : (
        selectedCountry && (
          <>
            <label htmlFor="city" className='font-bold'>Select City: </label>
            <select id="city" value={selectedCity} onChange={handleCityChange}>
              <option value="">Select a city</option>
              {availableCities.map((city, index) => (
                <option key={index} value={city}>
                  {city}
                </option>
              ))}
            </select>
          </>
        )
      )
}

Zusätzlich:

  • Wir überprüfen, ob selectedCountry die Option ‚Sonstiges‘ ist, und zeigen eine Texteingabe an.

  • Das Texteingabefeld hat einen otherCountry Zustand und die Handlerfunktion handleOtherCountryChange ist daran angehängt.

  • Wir steuern das Stadt-<select>-Element mit dem value-Attribut, indem wir es auf die Zustandvariable von selectedCity setzen. Der Ereignishandler handleCityChange ist ebenfalls angehängt, um onChange-Ereignisse zu behandeln.

  • Wir durchlaufen das availableCities-Array und erstellen dynamisch für jede Stadt im Array eine <option>.

  • Der key jeder Option wird auf einen index gesetzt und der value auf die city.

  • Jede Stadt wird als Text der Option angezeigt.

Das ist alles, was wir tun müssen, um ein funktionierendes Dropdown-Menü mit abhängigen Elementen mithilfe unserer statischen Daten zu haben.

Hier ist der gesamte Code zusammengefasst:

import React, { useState } from 'react';

const DependentDropdown = () => {
  // Statische Länderdaten
  const countries = [
    { id: 1, name: 'USA' },
    { id: 2, name: 'Canada' },
    { id: 3, name: 'Other' },
  ];

  // Statische Städtedaten entsprechend den Ländern
  const cities = {
    USA: ['New York', 'Los Angeles', 'Chicago'],
    Canada: ['Toronto', 'Vancouver', 'Montreal'],
  };

  // Zustand zur Speicherung des ausgewählten Landes, der Stadt und anderer Ländertexte
  const [selectedCountry, setSelectedCountry] = useState('');
  const [availableCities, setAvailableCities] = useState([]);
  const [selectedCity, setSelectedCity] = useState('');
  const [otherCountry, setOtherCountry] = useState(''); 

  // Behandlung der Länderänderung
  const handleCountryChange = (e) => {
    const country = e.target.value;
    setSelectedCountry(country);
    setAvailableCities(cities[country] || []);
    setSelectedCity(''); 
    if (country !== 'Other') {
      setOtherCountry('');
    }
  };

  // Behandlung der Städteänderung
  const handleCityChange = (e) => {
    setSelectedCity(e.target.value);
  };

  // Behandlung der Änderung der Eingabe für andere Länder
  const handleOtherCountryChange = (e) => {
    setOtherCountry(e.target.value);
  };

  return (
    <div className='text-center text-3xl'>
      <h1 className='font-extrabold text-5xl p-10'>Dependent Dropdown Example</h1>

      {/* Länder-Dropdown */}
      <label htmlFor="country" className='font-bold'>Select Country: </label>
      <select id="country" value={selectedCountry} onChange={handleCountryChange}>
        <option value="">Select a country</option>
        {countries.map((country) => (
          <option key={country.id} value={country.name}>
            {country.name}
          </option>
        ))}
      </select>

      {/* Stadt- oder Eingabe für andere Länder */}
      {selectedCountry === 'Other' ? (
        <>
          <label htmlFor="other-country" className='font-bold'>Please specify the country: </label>
          <input
            id="other-country"
            type="text"
            value={otherCountry}
            onChange={handleOtherCountryChange}
            placeholder="Enter country name"
          />
        </>
      ) : (
        selectedCountry && (
          <>
            <label htmlFor="city" className='font-bold'>Select City: </label>
            <select id="city" value={selectedCity} onChange={handleCityChange}>
              <option value="">Select a city</option>
              {availableCities.map((city, index) => (
                <option key={index} value={city}>
                  {city}
                </option>
              ))}
            </select>
          </>
        )
      )}
    </div>
  );
};

export default DependentDropdown;

Schritt 3: Verwenden Sie die Komponente

Um Ihre endgültigen Ergebnisse zu erhalten, müssen Sie die DependentDropdown-Komponente in Ihre App.js oder App.jsx importieren und sie im Rückgabebereich der App-Komponente platzieren.

import DependentDropdown from './DependentDropdown'

function App() {

  return (
    <DependentDropdown/>
  )
}

export default App

Vergessen Sie nicht, die Anwendung zu starten, indem Sie einen dieser Befehle eingeben:

npm start //für create react app
npm run dev //für react vite app

Schließlich sollte dies in Ihrem Browser gerendert werden:

Verarbeitung dynamischer Daten (API-Anfragen)

In realen Anwendungen sind die Listen für die Dropdowns möglicherweise nicht statisch. Stattdessen könnten sie von einer API oder einer JSON-Datei, die als API fungiert, abgerufen werden.

In diesem Beispiel werden wir Daten aus einer JSON-Datei lesen, um unser abhängiges Dropdown zu befüllen. Diese Praxis hat einige Vorteile, die sind:

  • Reduzierte Datenbanklast: Durch die Verwendung einer statischen JSON-Datei (oder einer vorgeladenen Datei) wird die Anzahl der Datenbankabfragen reduziert, die normalerweise benötigt würden, um Dropdown-Listen zu befüllen. Dies ist besonders nützlich, wenn die Dropdown-Optionen relativ statisch sind und sich nicht oft ändern.

  • Schnellere UI-Renderung: Da die Daten bereits auf der Client-Seite vorhanden sind, ist kein Round-Trip-Request an den Server erforderlich, wenn der Benutzer mit dem Dropdown interagiert. Dies kann die Benutzeroberfläche reaktiver erscheinen lassen.

Unsere JSON-Datei enthält Bundesstaaten und LGAs (Local Government Areas), die den Äquivalenten von Ländern und Städten entsprechen.

Die Daten in der JSON-Datei werden als Array von Objekten dargestellt, wobei jedes Objekt Schlüssel für Bundesstaat, Alias und LGAs hat. Der Schlüssel ‚LGAs‘ enthält ein Array.

So wird es dargestellt:

[
  {
    "state": "Adamawa",
    "alias": "adamawa",
    "lgas": [
      "Demsa",
      "Fufure",
      "Toungo",
      "Yola North",
      "Yola South"
    ]
  },
  {
    "state": "Akwa Ibom",
    "alias": "akwa_ibom",
    "lgas": [
      "Abak",
      "Uruan",
      "Urue-Offong/Oruko",
      "Uyo"
    ]
  },
//die restlichen Objekte
]

Diese Methode zur Erstellung eines dynamischen abhängigen Dropdowns aus einer API unterscheidet sich nicht wesentlich von dem vorherigen Beispiel, abgesehen von einigen geringfügigen Änderungen.

Hier ist, wie wir Daten aus einer JSON-Datei abgerufen und verwendet haben:

import React, { useEffect, useState } from "react";

function DependentDropdown() {
//Deklaration globaler Statusvariablen
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

//Datenabruf unter Verwendung des useEffect-Hooks
  useEffect(() => {
    fetch("nigeria-state-and-lgas.json") //JSON-Datei als URL festgelegt
      .then((res) => res.json())
      .then((data) => {
        setData(data);
        setLoading(false);
      })
      .catch((error) => {
        console.error("Error fetching data:", error);
        setLoading(false);
      });
  }, []);
  return loading ? <div>Loading...</div> : <Form data={data} />;

}
//Formular erhält Daten als props
function Form({ data }) {

//Deklaration lokaler Statusvariablen
  const [selectedState, setSelectedState] = useState("");
  const [selectedLga, setSelectedLga] = useState("");
  const [showList, setShowList] = useState(false);
  let sortedData = data.slice().sort((a, b) => a.state.localeCompare(b.state));
  const selectedData = sortedData.find((item) => item.state === selectedState);

//Handler-Funktion für Status
  function handleClickState(e) {
    setSelectedState(e.target.value);
    setShowList(true);
  }
//Handler-Funktion für LGA
  function handleClickLga(e) {
    setSelectedLga(e.target.value);
  }

  return (
    <div>
  <form onSubmit={handleFormSubmit}>
    <div>
      {/* Vorname */}
      <div>
        <label htmlFor="firstName">First Name</label>
        <input type="text"
          id="firstName"
          name="firstName"
          placeholder="Enter your first name"/>
      </div>

      {/* Nachname */}
      <div>
        <label htmlFor="lastName">
          Last Name
        </label>
        <input
          type="text"
          id="lastName"
          name="lastName"
          placeholder="Enter your last name"/>
      </div>
    </div>

    <div>
      <div>
        <select value={selectedState} onChange={handleClickState} name="state">
          <option value="" disabled>Choose your state</option>
          {sortedData.map((data) => (
            <option key={data.alias} value={data.state}>
              {data.state}
            </option>
          ))}
        </select>
      </div>
      {selectedData && showList && (
        <select value={selectedLga} onChange={handleClickLga} name="lga">
          <option value="" disabled>{`Choose your LGA in ${selectedState}`}</option>
          {selectedData.lgas.map((lgass) => (
            <option key={lgass} value={lgass}>
              {lgass}
            </option>
          ))}
        </select>
      )}

    </div>
    <div>
        <button type="submit">
          Submit
        </button>
      </div>
  </form>
</div>
  );
}

export default DependentDropdown;

Die Schlüsseländerung hier ist der Datenabruf unter Verwendung des useEffect-Hooks, der die Status- und LGA-Daten nur beim initialen Rendern abruft

So wird dies im Browser gerendert:

Zusammenfassung

In diesem Tutorial haben Sie gelernt, wie Sie abhängige Dropdowns in React sowohl mit statischen als auch mit dynamischen Daten erstellen können. Sie können diesen Dropdown-Typ nun in Ihren React-Anwendungen verwenden.

Wenn Ihnen dieser Artikel geholfen hat, können Sie mich auf LinkedIn für weitere programmbezogene Artikel und Beiträge kontaktieren.

Bis zum nächsten Mal!