【问题标题】:How do I add select options from an object如何从对象中添加选择选项
【发布时间】:2021-12-13 04:57:31
【问题描述】:

我正在尝试根据我拥有的对象创建一个下拉列表。我想不出一种不完全复杂的方法,而且我提出的解决方案也不起作用。我是反应和stackoverflow的新手,所以我不确定只是征求意见是否可以。如果不是,请原谅我。我正在用 React 构建它。有没有办法做到这一点,我错过了。如果您不应该在这里寻求帮助,再次抱歉

我已经创建了如下组件

const HardwearForm = ({isActive, Products, outputObj, setOutputObj}) => {

const handleSelect = e => {
    let newParentNode = e.target;
    let selectedNumber = newParentNode.options.selectedIndex;
    let choice = newParentNode.options[selectedNumber].value;               
    setOutputObj(outputObj[newParentNode.id] = choice);        
    console.log(outputObj)        
}        

useEffect(() => { 
    let parentNode = document.getElementById("make");
    Object.keys(Products[isActive]["hardwear"]).forEach(key => {            
    let newOption = document.createElement('option');
    newOption.value = key;
    newOption.innerText = key;
    parentNode.appendChild(newOption);
    })
},[isActive, Products]); 

return (
    <div>
    <select name="make" className="hardwear" id="make" onChange={handleSelect}>
        <option value="*">Manufacturer</option>
    </select>
    <select name="model" className="hardwear" id="model"></select>
    {isActive === "handset"|| isActive==="tablet"?
    <>
    <select name="storage" className="hardwear" id="storage""></select></>:""}
    {isActive === "handset"|| isActive==="tablet" ||isActive=== "watch"?
    <>
    <select name="color" className="hardwear"></select></>:""}
    {isActive === "handset"|| isActive==="watch"?
    <>
)

基本的想法是我有一个带有几个按钮的菜单。这些按钮更新 isActive 状态,然后导致 useEffect 运行并使用选项填充第一个选择。这很好用。然后我进行了设置,因此一旦选择了第一个下拉列表中的选择,它就会触发 handleSelect 函数,该函数对下一个选择执行相同的操作。我设置了一个空对象来存储所有选项。 setOutputObj(outputObj[newParentNode.id] = 选择);和该对象的键值对。问题是,如果您随后尝试更改所选选项,则会出错“TypeError: Cannot create property 'make' on string 'Huawei'”。

这是我正在使用的日期结构的示例。

"Fairphone": {
        "3+": {
            "color": ["Black"],
            "storage": ["64GB"], 
        }
    },
    "Doro": {
        "8050": {
            "color": ["Black"],
            "storage": ["16GB"], 
        }
    },
    "Mobiwire": {
        "Smart N12": {
            "color": ["Dark Metallic Blue"],
            "storage": ["16GB"], 
        }
    },

【问题讨论】:

  • 可以修改数据结构还是必须坚持的东西?
  • 目前我可以随意构建数据。我有 6 种产品类型的列表。上面是手机,分为制造商、型号、存储容量选项和颜色。重组结构会有帮助吗?

标签: javascript reactjs json oop react-hooks


【解决方案1】:

我对你的数据结构和你想要实现的目标有点困惑,但总的来说,动态设置来自对象的选择输入的选项我认为最好使用 array.map 而不是尝试直接修改 DOM。

例如: https://codesandbox.io/s/compassionate-buck-8sir5?file=/src/App.js

import { useState } from "react";
import "./styles.css";

const productsByManufacturers = {
  "Manufacturer 1": ["product 1", "product 2", "product 3"],
  "Manufacturer 2": ["product 4", "product 5"]
};

export default function App() {
  const [manufacturer, setManufacturer] = useState("");

  return (
    <div className="App" style={{ display: "flex", flexDirection: "column" }}>
      <label>Select Manufacturer:</label>
      <select
        value={manufacturer}
        onChange={(e) => setManufacturer(e.target.value)}
      >
        <option value="" disabled>
          Select a manufacturer
        </option>
        {Object.keys(productsByManufacturers).map((manufacturer) => (
          <option value={manufacturer}>{manufacturer}</option>
        ))}
      </select>

      {manufacturer !== "" && (
        <div
          style={{ marginTop: 20, display: "flex", flexDirection: "column" }}
        >
          <label>Select Product:</label>
          <select>
            {productsByManufacturers[manufacturer].map((product) => (
              <option value={product}>{product}</option>
            ))}
          </select>
        </div>
      )}
    </div>
  );
}

【讨论】:

  • 我之所以将其结构化,是因为我希望第一个下拉列表提供第一个分支选项,然后仅根据该分支中可用的内容打开其他选项。我试图避免用户能够选择在他们选择的范围内不可用的存储选项。如果我按照您上面的方式进行操作,那么如果我理解您的话,它仅适用于两个级别的可能性。一个制造商和一个产品。我真的需要颜色和存储选项这两个进一步的选项
  • 它只适用于两个级别,因为我的虚拟数据中只有两个级别。如果您愿意,您可以以相同的方式添加更多图层。我认为重组数据会更好。您应该有一个产品对象数组。每个产品对象都应该有每个属性的键。例如[{名称:XXX,制造商:XXX,颜色:[XXX,XXX],存储:[XXX,XXX]},...更多产品]。我认为使用 array.filter 过滤您的产品会更容易
  • 你的意思是这样的:[ { manufacturer : "Fairphone", model : "3+", colors: ["black", "green", "red"], storage : ["128GB" , "256GB"] }, { manufacturer : "Apple", model : "iphone 12 pro max"", colors: ["black", "green", "red"], storage : ["128GB" , "256GB"] }, ]我不知道这会有什么帮助。你看,我希望第一个下拉列表始终填充所有制造商选项,然后如果他们选择 Apple,所有苹果型号都会显示在下一个下拉列表中。然后,当他们选择模型时,下一个下拉菜单仅显示该模型的存储选项。
猜你喜欢
  • 2014-12-30
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-15
  • 1970-01-01
  • 2014-03-03
相关资源
最近更新 更多