问题
Excuse my lack of knowledge as i am fairly new to ReactJS. I'm trying to create a dynamic Dropdown system where i have The Country DropDown and the cities DropDown, and i want to fetch my data from a const that has multiple arrays in it, here's an example of the const i have:
const countries = {"France":["Paris","Marseille","Lille","Lyon"],
"Usa":["New York","San Francisco","Austin","Dallas"]
};
I know that i need to use the useState and the useEffect hooks and a function to handle the event changes.
What i'm having a hard time to figure out is how to deal with the data format, especially that the variables inside the const can't be accessed easily, it would've been much easier if the data was in this shape:
const countries =[
{ name: 'Usa', cities: ["New York", "San Francisco", "Austin", "Dallas"]},
{ name: 'France', cities: ["Paris", "Marseille", "Lille", "Lyon"]},
]
But unfortunately the first sample is the shape of data i have to deal with and i can't modify it manually because i have a very large sample of data. So if anyone could just direct me briefly into the steps i should make, i would be very thankful.
回答1:
You can abstract the country in a separate list with the "Object.keys" and use the first one to get the cities. I think in this case you don't need to use "useEffect".
Example here: https://codesandbox.io/s/dropdown-react-p0nj7
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [cities, setCities] = useState([]);
const [selectedCounty, setSelectedCountry] = useState("");
const [selectedCity, setSelectedCity] = useState("");
const countries = {
France: ["Paris", "Marseille", "Lille", "Lyon"],
Usa: ["New York", "San Francisco", "Austin", "Dallas"],
Brazil: ["São Paulo", "Rio de Janeiro", "Salvador"]
};
const countryList = Object.keys(countries).map(key => ({
name: key
}));
function handleCountrySelect(e) {
console.log("Selected country", e.target.value);
const countrySel = e.target.value;
const citiesSel = countrySel !== "" ? countries[countrySel] : "";
setSelectedCountry(countrySel);
setCities(citiesSel);
setSelectedCity("");
}
function handleCitySelect(e) {
console.log("Selected city", e.target.value);
const citiesSel = e.target.value;
setSelectedCity(citiesSel);
}
return (
<div className="App">
<h1>Example DropDown Coutries and Cities</h1>
<div className="Container">
<select
name="Countries"
onChange={e => handleCountrySelect(e)}
value={selectedCounty}
>
<option value="">Select the country</option>
{countryList.map((country, key) => (
<option key={key} value={country.name}>
{country.name}
</option>
))}
</select>
<select
name="Cities"
onChange={e => handleCitySelect(e)}
value={selectedCity}
>
<option value="">Select the city</option>
{cities.map((city, key) => (
<option key={key} value={city}>
{city}
</option>
))}
</select>
</div>
</div>
);
}
回答2:
so,
- we gotta traverse the countries array and get the list of distinct countries for first dropdown (check useEffect hook)
- store the selected Country from this first dropdown inside the state in
selectedCountry - use the selected country to display the relevant cities list (
countries[selectedCountry].map...inside return);
relevant JS:
import React, { useState, useEffect } from "react";
const countries = {
France: ["Paris", "Marseille", "Lille", "Lyon"],
Usa: ["New York", "San Francisco", "Austin", "Dallas"]
};
const Dropdown = () => {
const [countryData, setCountryData] = useState(["Usa"]);
const [selectedCountry, setSelectedCountry] = useState("");
const checkInsertInArray = newCountry => {
let findStatus = countryData.find(x => {
return x === newCountry;
});
if (!findStatus) {
setCountryData([...countryData, newCountry]);
}
};
const countryChange = event => {
if (event.target.value) {
setSelectedCountry(event.target.value);
}
};
useEffect(() => {
Object.keys(countries).forEach(country => {
checkInsertInArray(country);
});
});
return (
<>
<span>Country:</span>
<select onChange={countryChange}>
<option value="" />
{countryData.map(allCountries => {
return <option value={allCountries}>{allCountries}</option>;
})}
</select>
<br />
{selectedCountry ? (
<>
<span>City:</span>{" "}
<select>
<option value="" />
{countries[selectedCountry].map(allCountries => {
return <option value={allCountries}>{allCountries}</option>;
})}
</select>
</>
) : (
<span>City: Please select a country first</span>
)}
</>
);
};
export default Dropdown;
working stackblitz here
来源:https://stackoverflow.com/questions/62239420/steps-to-populate-dynamic-dropdown-using-arrays-in-reactjs-using-react-hooks