如何在 React 中创建带有变体下拉菜单的产品页面?
How to create a product page with variant dropdowns in react?
创建带有变体下拉菜单的产品页面的最佳方法是什么?
我有一个带有变体列表的产品,例如:
[{size: "small", color: "red", material: "metal"},
{size: "small", color: "red", material: "wood"},
{size: "medium", color: "blue", material: "plastic"},
{size: "large", color: "blue", material: "metal"},
{size: "large", color: "yellow", material: "wood"}]
我所做的是创建 3 个下拉菜单,一个用于大小,一个用于颜色,另一个用于 material,其中列出了所有可用选项。
我需要一种方法来在更改其中一个下拉菜单时影响其他 2 个下拉菜单,以便下拉菜单中只有可用的变体可用。
例如,如果用户从第一个下拉菜单中选择“小”,颜色下拉菜单应该只显示红色,material 下拉菜单应该只显示金属和木头。
实现此目标的最佳方法是什么?
我在这个codesandbox中创建了3个下拉菜单的例子:
https://codesandbox.io/s/divine-water-vz8tv?file=/src/App.js
每次 select 之一的值发生变化时,您都可以收集选项。当 re-selecting 主要(在 setSize
重置 color
和 material
,在 setColor
重置时,它仍然只是完成依赖 selects 的重置material
).
const products = [
{ size: "small", color: "red", material: "metal" },
{ size: "small", color: "red", material: "wood" },
{ size: "medium", color: "blue", material: "plastic" },
{ size: "large", color: "blue", material: "metal" },
{ size: "large", color: "yellow", material: "wood" }
];
export default function App() {
const [size, setSize] = React.useState();
const [color, setColor] = React.useState();
const [material, setMaterial] = React.useState();
const sizeOptions = products
.map((p) => p.size)
.filter((v, i, a) => a.indexOf(v) === i)
.map((size) => ({ label: size, value: size }));
const colorOptions = products
.filter((p) => size && p.size === size.value)
.map((p) => p.color)
.filter((v, i, a) => a.indexOf(v) === i)
.map((color) => ({ label: color, value: color }));
const materialOptions = products
.filter(
(p) => size && p.size === size.value && color && p.color === color.value
)
.map((p) => p.material)
.filter((v, i, a) => a.indexOf(v) === i)
.map((material) => ({ label: material, value: material }));
return (
<div className="App">
<Select value={size} onChange={setSize} options={sizeOptions} />
<Select
value={color}
onChange={setColor}
options={colorOptions}
isDisabled={!size}
/>
<Select
value={material}
onChange={setMaterial}
options={materialOptions}
isDisabled={!color}
/>
</div>
);
}
创建带有变体下拉菜单的产品页面的最佳方法是什么? 我有一个带有变体列表的产品,例如:
[{size: "small", color: "red", material: "metal"},
{size: "small", color: "red", material: "wood"},
{size: "medium", color: "blue", material: "plastic"},
{size: "large", color: "blue", material: "metal"},
{size: "large", color: "yellow", material: "wood"}]
我所做的是创建 3 个下拉菜单,一个用于大小,一个用于颜色,另一个用于 material,其中列出了所有可用选项。
我需要一种方法来在更改其中一个下拉菜单时影响其他 2 个下拉菜单,以便下拉菜单中只有可用的变体可用。
例如,如果用户从第一个下拉菜单中选择“小”,颜色下拉菜单应该只显示红色,material 下拉菜单应该只显示金属和木头。
实现此目标的最佳方法是什么?
我在这个codesandbox中创建了3个下拉菜单的例子: https://codesandbox.io/s/divine-water-vz8tv?file=/src/App.js
每次 select 之一的值发生变化时,您都可以收集选项。当 re-selecting 主要(在 setSize
重置 color
和 material
,在 setColor
重置时,它仍然只是完成依赖 selects 的重置material
).
const products = [
{ size: "small", color: "red", material: "metal" },
{ size: "small", color: "red", material: "wood" },
{ size: "medium", color: "blue", material: "plastic" },
{ size: "large", color: "blue", material: "metal" },
{ size: "large", color: "yellow", material: "wood" }
];
export default function App() {
const [size, setSize] = React.useState();
const [color, setColor] = React.useState();
const [material, setMaterial] = React.useState();
const sizeOptions = products
.map((p) => p.size)
.filter((v, i, a) => a.indexOf(v) === i)
.map((size) => ({ label: size, value: size }));
const colorOptions = products
.filter((p) => size && p.size === size.value)
.map((p) => p.color)
.filter((v, i, a) => a.indexOf(v) === i)
.map((color) => ({ label: color, value: color }));
const materialOptions = products
.filter(
(p) => size && p.size === size.value && color && p.color === color.value
)
.map((p) => p.material)
.filter((v, i, a) => a.indexOf(v) === i)
.map((material) => ({ label: material, value: material }));
return (
<div className="App">
<Select value={size} onChange={setSize} options={sizeOptions} />
<Select
value={color}
onChange={setColor}
options={colorOptions}
isDisabled={!size}
/>
<Select
value={material}
onChange={setMaterial}
options={materialOptions}
isDisabled={!color}
/>
</div>
);
}