如何从对象中添加选择选项
Posted
技术标签:
【中文标题】如何从对象中添加选择选项【英文标题】:How do I add select options from an object 【发布时间】:2021-12-13 04:57:31 【问题描述】:我正在尝试根据我拥有的对象创建一个下拉列表。我想不出一种不完全复杂的方法,而且我提出的解决方案也不起作用。我是反应和***的新手,所以我不确定只是征求意见是否可以。如果不是,请原谅我。我正在用 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 种产品类型的列表。上面是手机,分为制造商、型号、存储容量选项和颜色。重组结构会有帮助吗? 【参考方案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,所有苹果型号都会显示在下一个下拉列表中。然后,当他们选择模型时,下一个下拉菜单仅显示该模型的存储选项。以上是关于如何从对象中添加选择选项的主要内容,如果未能解决你的问题,请参考以下文章