使用反应钩子在 REACTJS 中使用数组填充动态下拉列表的步骤

Steps to populate dynamic Dropdown using arrays in REACTJS using react hooks

请原谅我缺乏知识,因为我对 ReactJS 还很陌生。我正在尝试创建一个动态下拉系统,其中我有国家/地区下拉列表和城市下拉列表,我想从其中包含多个数组的常量中获取我的数据,这是我拥有的常量示例:

const countries = {"France":["Paris","Marseille","Lille","Lyon"],
                   "Usa":["New York","San Francisco","Austin","Dallas"]
                  };

我知道我需要使用 useState 和 useEffect 挂钩以及一个函数来处理事件更改。

我很难弄明白的是如何处理数据格式,尤其是 const 中的变量不容易访问,如果数据是在这个形状中:

const countries =[
                   { name: 'Usa',  cities: ["New York", "San Francisco", "Austin", "Dallas"]},
                   { name: 'France', cities: ["Paris", "Marseille", "Lille", "Lyon"]},
                 ]

但不幸的是,第一个样本是我必须处理的数据形状,我无法手动修改它,因为我有非常大的数据样本。 所以如果有人能简单地指导我进入我应该做的步骤, 我将不胜感激。

所以,

  • 我们必须遍历国家数组并为第一个下拉列表获取不同国家的列表(检查 useEffect 钩子)
  • 将第一个下拉列表中的所选国家/地区存储在 selectedCountry
  • 的州内
  • 使用所选国家显示相关城市列表(countries[selectedCountry].map... inside return);

相关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;

工作stackblitz here

您可以使用“Object.keys”在单独的列表中提取国家/地区,并使用第一个列表获取城市。我认为在这种情况下你不需要使用“useEffect”。

此处示例: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>
  );
}