使用react-hooks在 REACTJS 中使用数组填充动态下拉列表的步骤

IT技术 arrays reactjs typescript drop-down-menu
2021-04-25 18:47:07

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

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"]},
                 ]

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

2个回答

所以,

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

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

这里工作堆栈闪电战

您可以使用“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>
  );
}