In veel webapplicaties komen we vaak formulieren tegen waarbij het selecteren van een optie in een dropdown een nieuwe set opties ontgrendelt in een andere. Deze onderling verbonden dropdowns, algemeen bekend als afhankelijke of cascaderende dropdowns, spelen een cruciale rol bij het creëren van een naadloze en intuïtieve ervaring bij het invullen van formulieren.
Of het nu gaat om het selecteren van een land om bijbehorende staten weer te geven of het kiezen van een productcategorie om specifieke items weer te geven, deze dropdowns vereenvoudigen complexe keuzes voor iedereen. Voor ontwikkelaars is het implementeren van afhankelijke dropdowns een praktische uitdaging die logica, gebruiksvriendelijkheid en dynamische gegevensverwerking combineert.
In deze tutorial leer je hoe je dit type dropdown kunt implementeren in je React-applicatie.
Inhoudsopgave
Wat is een Afhankelijk Dropdown?
Een afhankelijk dropdown is een UI-element waarin de beschikbare opties in een dropdown worden bepaald door de selectie die in een andere dropdown is gemaakt. Neem bijvoorbeeld een scenario waarin je twee dropdowns hebt:
-
Land Dropdown: De gebruiker selecteert een land.
-
Stad Dropdown: Op basis van het geselecteerde land wordt de lijst met beschikbare steden in de tweede dropdown dienovereenkomstig gefilterd.
Dit soort interactie is cruciaal voor formulieren die complexe, contextgevoelige gegevensinvoer vereisen.
Hoe Werkt een Afhankelijk Dropdown?
Afhankelijk dropdowns werken door de opties van de tweede dropdown dynamisch bij te werken op basis van de waarde die in de eerste dropdown is geselecteerd. Deze dynamische wijziging wordt doorgaans bereikt door:
-
Luisteren naar gebruikersinvoer: Wanneer de gebruiker een optie in de eerste dropdown selecteert, triggert een gebeurtenis (meestal onChange) een functie om de staat bij te werken.
-
Het ophalen van nieuwe gegevens: Deze bijgewerkte status kan worden gebruikt om de bestaande gegevens te filteren of om een API-oproep te doen om de nieuwe lijst met opties op te halen.
-
Het renderen van nieuwe gegevens: De tweede vervolgkeuzelijst wordt vervolgens bijgewerkt met de nieuwe opties, waardoor de gebruiker relevante keuzes krijgt.
Stappen om afhankelijke vervolgkeuzelijsten te maken in React
Stap 1: Stel je React-project in
Als je nieuw bent in React en wilt meedoen, bekijk dan de Vite-documentatie en volg de stappen om je React-project te maken. Als je klaar bent, kom dan hier terug en laten we doorgaan met bouwen.
Als je al een React-project hebt dat je wilt gebruiken, is dat ook prima.
Stap 2: Structuur van het Component
Voor eenvoud, laten we ervan uitgaan dat we een afhankelijke vervolgkeuzelijst met twee niveaus bouwen waarbij de eerste vervolgkeuzelijst je een land laat kiezen en de tweede vervolgkeuzelijst steden weergeeft op basis van het geselecteerde land.
Ook in de landenkeuzelijst hebben we een andere optie voor het invoeren van een landnaam die niet in de landenopties is opgenomen. De gebruiker kan vervolgens hun land invoeren in een tekstinvoer.
Maak eerst een nieuw bestand met de naam DependentDropdown.js
of DependentDropdown.jsx
. Definieer binnen dit bestand een functionele component genaamd DependentDropdown
.
Nu zullen we de volgende stappen doorlopen om onze afhankelijke keuzelijst te bouwen:
Declareer Variabelen voor het Opslaan van Gegevens
We moeten statische gegevens maken voor de waarden van onze landen en steden:
// Statische landgegevens
const countries = [
{ id: 1, name: 'USA' },
{ id: 2, name: 'Canada' },
{ id: 3, name: 'Other' },
];
// Statische stadsgegevens die overeenkomen met landen
const cities = {
USA: ['New York', 'Los Angeles', 'Chicago'],
Canada: ['Toronto', 'Vancouver', 'Montreal'],
};
-
countries
is een array van objecten. Elk object heeft eigenschappen vanid
enname
. -
cities
is een object met landnamen als sleutels en de waarden als een array van steden.
Declareer Toestand Variabelen
Voor elke selectie van een land of steden willen we in staat zijn om de geselecteerde waarden bij te houden. We willen ook in staat zijn om de stedenoptie in te vullen nadat een landselectie is gemaakt. Om dat te doen, moeten we enkele toestanden declareren.
Als het concept van staat nieuw voor je is, kun je mijn artikel over staat hier lezen.
const [selectedCountry, setSelectedCountry] = useState('');
const [availableCities, setAvailableCities] = useState([]);
const [selectedCity, setSelectedCity] = useState('');
const [otherCountry, setOtherCountry] = useState('');
-
De
selectedCountry
staat is gedeclareerd en de initiële waarde is ingesteld op een lege string. -
De
availableCities
staat is gedeclareerd en de initiële waarde is ingesteld op een lege array. -
De
selectedCity
staat is gedeclareerd en de initiële waarde is ingesteld op een lege string. -
De
otherCountry
staat is gedeclareerd en de initiële waarde is ingesteld op een lege string.
Evenementen Afhandelen
In het proces van het maken van een selectie in de dropdown, willen we dat er enkele acties worden uitgevoerd. Evenementhandlers stellen ons in staat om dat te doen in het geval van een evenement, dat in dit geval het onChange
evenement is.
const handleCountryChange = (e) => {
const country = e.target.value;
setSelectedCountry(country);
setAvailableCities(cities[country] || []);
setSelectedCity('');
if (country !== 'Other') {
setOtherCountry('');
}
};
Hier is wat er aan de hand is in de handleCountryChange
functie:
-
Pak de waarde van de geselecteerde optie in de dropdown (het land dat werd geselecteerd).
-
De
setSelectedCountry
bijwerkt de statusvariabele (selectedCountry) met het nieuw geselecteerde land. -
cities[country]
zoekt de lijst met steden voor het geselecteerde land op uit hetcities
object.-
Als
cities[country]
wordt gevonden, stelt het die lijst met steden in als de beschikbare steden. -
Als er geen steden worden gevonden voor het geselecteerde land (
cities[country]
is ongedefinieerd), zorgt de|| []
ervoor dat een lege array ([]
) wordt gebruikt als een fallback, om fouten te voorkomen bij het weergeven van de steden.
-
-
Wanneer de gebruiker de landkeuze verandert, reset de
setSelectedCity
functie deselectedCity
naar een lege string. -
Als het geselecteerde land niet ‘Overig’ is, wordt de
otherCountry
status gereset naar een lege string. Dit zorgt ervoor dat als de gebruiker eerder iets in het “Overig” invoerveld heeft getypt, die tekst wordt gewist zodra ze een ander land selecteren (bijvoorbeeld “VS” of “Canada”).
Voor de ‘Overig’ landkeuze hoeven we alleen de waarde bij te houden die in het invoerveld is ingevoerd. De setOtherCountry
functie werkt de ingevoerde waarde bij. En zo wordt het gedaan:
const handleOtherCountryChange = (e) => {
setOtherCountry(e.target.value);
};
Voor de wijziging van de steden hoeven we niet veel te doen omdat het geselecteerde land bepaalt welke steden worden weergegeven. Alles wat we hoeven te doen is de selectedCity
bijwerken naar de waarde van de geselecteerde optie in de dropdown, wat de geselecteerde stad is.
In React zorgt de updaterfunctie voor het bijwerken van statusvariabelen, dus de setSelectedCity
behandelt dit in dit geval.
De handleCityChange
functie zal zijn:
const handleCityChange = (e) => {
setSelectedCity(e.target.value);
};
JSX retourneren
De DependentDropdown
component rendert drie hoofd elementen: de land dropdown, de stad dropdown en het land tekstinvoer.
Een dropdown in HTML is een combinatie van de <select>
en <option>
elementen. Om de waarde van elementen bij te houden, zullen we statusvariabelen aan hen koppelen zodat we ze kunnen controleren. Dit wordt ‘Controlling Elements’ genoemd, terwijl de elementen zelf ‘Controlled Elements’ in React worden genoemd.
Om het land <select>
element te controleren, geven we het een value
attribuut van selectedCountry
en koppelen we ook de handleCountryChange
functie eraan.
<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>
Ook,
-
Binnen de
<option>
mappen we over decountries
array en creëren we dynamisch een<option>
voor elk landobject in de array. -
De
name
van elk land wordt weergegeven als de tekst van de optie. -
Elke optie’s
key
is ingesteld op hetid
van het land envalue
is ingesteld op denaam
van het land. -
De
key
helpt React om de lijst efficiënt te beheren bij het opnieuw renderen.
De dropdown voor steden wordt conditioneel weergegeven op basis van het geselecteerde land. Als de optie ‘Overig’ is gekozen, wordt er een tekstinvoerveld weergegeven zodat de gebruiker het land kan specificeren. Anders, als een geldig land is geselecteerd, wordt een dropdown voor steden met relevante opties getoond.
{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>
</>
)
)
}
Daarnaast:
-
We controleren of
selectedCountry
de optie ‘Overig’ is en tonen een tekstinvoer. -
De tekstinvoer heeft een
otherCountry
status en dehandleOtherCountryChange
handlerfunctie eraan gekoppeld. -
We controleren het
<select>
element voor steden met behulp van hetvalue
attribuut, dat is ingesteld op de statusvariabele vanselectedCity
. De gebeurtenishandler,handleCityChange
, is ook gekoppeld omonChange
gebeurtenissen te verwerken. -
We lopen over de
availableCities
array en maken dynamisch een<option>
voor elke stad in de array. -
Elke optie’s
key
is ingesteld op eenindex
envalue
is ingesteld op decity
. -
Elke stad wordt weergegeven als de tekst van de optie.
Dat is alles wat we hoeven te doen om een functionele afhankelijke dropdown te hebben met behulp van onze statische gegevens.
Hier is alle code samengevoegd:
import React, { useState } from 'react';
const DependentDropdown = () => {
// Statische landgegevens
const countries = [
{ id: 1, name: 'USA' },
{ id: 2, name: 'Canada' },
{ id: 3, name: 'Other' },
];
// Statische stadsgegevens die overeenkomen met landen
const cities = {
USA: ['New York', 'Los Angeles', 'Chicago'],
Canada: ['Toronto', 'Vancouver', 'Montreal'],
};
// Status om het geselecteerde land, de stad en andere landtekst vast te houden
const [selectedCountry, setSelectedCountry] = useState('');
const [availableCities, setAvailableCities] = useState([]);
const [selectedCity, setSelectedCity] = useState('');
const [otherCountry, setOtherCountry] = useState('');
// Omgaan met landwijzigingen
const handleCountryChange = (e) => {
const country = e.target.value;
setSelectedCountry(country);
setAvailableCities(cities[country] || []);
setSelectedCity('');
if (country !== 'Other') {
setOtherCountry('');
}
};
// Omgaan met stadswijzigingen
const handleCityChange = (e) => {
setSelectedCity(e.target.value);
};
// Omgaan met wijzigingen in andere landinvoer
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>
{/* Land 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>
{/* Stads- of andere landinvoer */}
{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;
Stap 3: Gebruik de Component
Om je uiteindelijke resultaten te krijgen, moet je de DependentDropdown
component importeren in je App.js
of App.jsx
en deze binnen de returnsectie van de App-component plaatsen.
import DependentDropdown from './DependentDropdown'
function App() {
return (
<DependentDropdown/>
)
}
export default App
Vergeet niet de applicatie uit te voeren door een van deze opdrachten in te voeren:
npm start //voor create react app
npm run dev //voor react vite app
Ten slotte, dit zou in je browser moeten worden weergegeven:
Omgaan met Dynamische Gegevens (API-verzoeken)
In echte toepassingen zijn de lijsten voor de dropdowns mogelijk niet statisch. In plaats daarvan kunnen ze worden opgehaald uit een API of een JSON-bestand dat als een API fungeert.
In dit voorbeeld zullen we gegevens uit een JSON-bestand lezen om onze afhankelijke dropdown te vullen. Deze praktijk heeft enkele voordelen, namelijk:
-
Verminderde databasebelasting: Door een statisch JSON-bestand (of een voorgeüpload bestand) te gebruiken, vermindert u het aantal databasequery’s dat anders nodig zou zijn om keuzelijsten te vullen. Dit is vooral nuttig als de opties in de keuzelijsten vrij statisch zijn en niet vaak veranderen.
-
Snellere UI-rendering: Aangezien de gegevens al aan de clientzijde beschikbaar zijn, is er geen behoefte aan een round-trip verzoek naar de server elke keer dat de gebruiker met de keuzelijst interactie heeft. Dit kan de interface responsiever laten aanvoelen.
Ons JSON-bestand bevat staten en LGAs (Lokale Overheidsgebieden), die de equivalenten zijn van landen en steden.
De gegevens in het JSON-bestand worden weergegeven als een array van objecten, waarbij elk object sleutels heeft voor staat, alias, en lgas. De sleutel ‘lgas’ bevat een array.
Hier is hoe het wordt weergegeven:
[
{
"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"
]
},
//de rest van de objecten
]
Deze methode om een dynamisch afhankelijk dropdown-menu vanuit een API te creëren, verschilt niet veel van het vorige voorbeeld, behalve enkele kleine aanpassingen.
Hier is hoe we gegevens uit een JSON-bestand hebben opgehaald en gebruikt:
import React, { useEffect, useState } from "react";
function DependentDropdown() {
//globale statusvariabelen declareren
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
//gegevens ophalen met behulp van de useEffect-hook
useEffect(() => {
fetch("nigeria-state-and-lgas.json") //JSON-bestand ingesteld als URL
.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} />;
}
//formulier ontvangt gegevens als props
function Form({ data }) {
//lokale statusvariabelen declareren
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);
//handlerfunctie voor status
function handleClickState(e) {
setSelectedState(e.target.value);
setShowList(true);
}
//handlerfunctie voor Lga
function handleClickLga(e) {
setSelectedLga(e.target.value);
}
return (
<div>
<form onSubmit={handleFormSubmit}>
<div>
{/* Voornaam */}
<div>
<label htmlFor="firstName">First Name</label>
<input type="text"
id="firstName"
name="firstName"
placeholder="Enter your first name"/>
</div>
{/* Achternaam */}
<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;
De belangrijkste wijziging hier is het ophalen van gegevens met behulp van de useEffect
hook, die de staten en LGA-gegevens alleen bij de eerste weergave ophaalt
Hier is hoe dit in de browser wordt weergegeven:
Conclusie
In deze tutorial heb je geleerd hoe je afhankelijke dropdowns in React kunt maken met zowel statische als dynamische gegevens. Je kunt nu dit soort dropdowns gebruiken in je React-toepassingen.
Als je dit artikel nuttig vond, kun je contact met me opnemen op LinkedIn voor meer artikelen en berichten gerelateerd aan programmeren.
Tot de volgende keer!
Source:
https://www.freecodecamp.org/news/how-to-build-dependent-dropdowns-in-react/