使用 Material-UI 反应创建动态 Select 和选项元素
React Creating Dynamic Select and Option Elements with Material-UI
所以,老实说,我原以为这会花费我 15 分钟,但我现在已经起床了大约 5 个小时。最让我困扰的是,我知道这是一个简单的解决方案,而且我也尝试了几种不同的方法。
我有一个 React 应用程序,在诊断组件中,我有两个下拉元素,允许用户选择他们设备的品牌和型号。 What I'm trying to do is allow the user to choose which Make they have, and when the make dropdown is selected, the models dropdown populates automatically.
这是我的 MakeandModel.js 文件:
import React, { useState, useEffect } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import FormControl from '@material-ui/core/FormControl';
import InputLabel from '@material-ui/core/InputLabel';
import Select from '@material-ui/core/Select';
import MenuItem from '@material-ui/core/MenuItem';
import makeandmodel_DATA from './makeandmodel_DATA';
const useStyles = makeStyles((theme) => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}));
console.log(makeandmodel_DATA);
export default () => {
const classes = useStyles();
const [data, setData] = useState();
const [make, setMake] = useState('');
const [model, setModel] = useState('');
useEffect(() => {
});
const handleMakeChange = (event) => (
setMake(event.target.value)
);
const handleModelChange = (event) => (
setModel(event.target.value)
);
return (
<>
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Make</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={make}
onChange={handleMakeChange}
label="Make"
>
<MenuItem value="">
<em>Choose a Make</em>
</MenuItem>
{makeandmodel_DATA.map((make, index) => (
<MenuItem key={index} value={make.name}>{make.name}</MenuItem>
))}
</Select>
</FormControl>
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Model</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={model}
onChange={handleModelChange}
label="Model"
>
<MenuItem value="">
<em>Choose a Model</em>
</MenuItem>
</Select>
</FormControl>
<br />
</>
);
};
我还有一些示例数据正在导入,以尝试填充我的品牌和型号下拉列表。这是 makeandmodel_DATA.json 文件中的代码:
[
{
"name": "Dyson",
"models": [
{
"name": "v12"
},
{
"name": "v10"
},
{
"name": "ball"
}
]
},
{
"name": "Oreck",
"models": [
{
"name": "Upright"
},
{
"name": "Unique"
},
{
"name": "XL"
}
]
},
{
"name": "Electrolux",
"models": [
{
"name": "Classic"
},
{
"name": "Vintage"
},
{
"name": "New School"
}
]
},
{
"name": "Kirby",
"models": [
{
"name": "Heavy"
},
{
"name": "Light"
},
{
"name": "Regular"
}
]
},
{
"name": "Hoover",
"models": [
{
"name": "Windtunnel"
},
{
"name": "Back"
},
{
"name": "Upright"
}
]
}
]
我尝试映射导入的数据,但每次我这样做来查找模型时,我最终都会返回未定义的。
我也尝试过连接 useEffect 函数,但也无法弄清楚如何正确地连接它。
就像我说的,我觉得解决方案非常简单,但我忽略了一些基本的东西。我真的只是在寻找一个看起来干净且运行良好的超级简单的解决方案。如果您需要任何其他信息来帮助我们解决此问题,请询问。
提前致谢!
这里的最佳做法是创建一个对象,在其中以 Make
名称保存模型。
const models = React.useMemo(() => {
const modelsValues = {};
makeandmodel_DATA.forEach(({ name, models }) => {
modelsValues[name] = models;
})
return modelsValues;
})
您只需要保存模型名称即可。
然后你需要访问 selected Make
模型,最后你的 Make
select 将是这样的:
{make && <FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Model</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={model}
onChange={handleModelChange}
label="Model"
>
<MenuItem value="">
<em>Choose a Model</em>
</MenuItem>
{models[make] ? models[make].map(model=> {
// Here goes your models option
return <MenuItem value="">
<em>Choose a Model</em>
</MenuItem>
}) : null
}
</Select>
</FormControl>}
也许我打错了,但如果你能给我一个沙箱,这可以更容易修复。
这是一个很好的解决方案!
我做了同样的事情,我在地图函数中添加了一个索引,为每个 MenuItem 添加了一个键,并将每个 MenuItem 的值属性和子项设置为 model.name
{make && <FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Model</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={model}
onChange={handleModelChange}
label="Model"
>
<MenuItem value="">
<em>Choose a Model</em>
</MenuItem>
{models[make]
? models[make].map((model, index) => (
<MenuItem key={index} value={model.name}>{model.name}</MenuItem>
))
: null
}
</Select>
</FormControl>}
所以,老实说,我原以为这会花费我 15 分钟,但我现在已经起床了大约 5 个小时。最让我困扰的是,我知道这是一个简单的解决方案,而且我也尝试了几种不同的方法。
我有一个 React 应用程序,在诊断组件中,我有两个下拉元素,允许用户选择他们设备的品牌和型号。 What I'm trying to do is allow the user to choose which Make they have, and when the make dropdown is selected, the models dropdown populates automatically.
这是我的 MakeandModel.js 文件:
import React, { useState, useEffect } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import FormControl from '@material-ui/core/FormControl';
import InputLabel from '@material-ui/core/InputLabel';
import Select from '@material-ui/core/Select';
import MenuItem from '@material-ui/core/MenuItem';
import makeandmodel_DATA from './makeandmodel_DATA';
const useStyles = makeStyles((theme) => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}));
console.log(makeandmodel_DATA);
export default () => {
const classes = useStyles();
const [data, setData] = useState();
const [make, setMake] = useState('');
const [model, setModel] = useState('');
useEffect(() => {
});
const handleMakeChange = (event) => (
setMake(event.target.value)
);
const handleModelChange = (event) => (
setModel(event.target.value)
);
return (
<>
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Make</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={make}
onChange={handleMakeChange}
label="Make"
>
<MenuItem value="">
<em>Choose a Make</em>
</MenuItem>
{makeandmodel_DATA.map((make, index) => (
<MenuItem key={index} value={make.name}>{make.name}</MenuItem>
))}
</Select>
</FormControl>
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Model</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={model}
onChange={handleModelChange}
label="Model"
>
<MenuItem value="">
<em>Choose a Model</em>
</MenuItem>
</Select>
</FormControl>
<br />
</>
);
};
我还有一些示例数据正在导入,以尝试填充我的品牌和型号下拉列表。这是 makeandmodel_DATA.json 文件中的代码:
[
{
"name": "Dyson",
"models": [
{
"name": "v12"
},
{
"name": "v10"
},
{
"name": "ball"
}
]
},
{
"name": "Oreck",
"models": [
{
"name": "Upright"
},
{
"name": "Unique"
},
{
"name": "XL"
}
]
},
{
"name": "Electrolux",
"models": [
{
"name": "Classic"
},
{
"name": "Vintage"
},
{
"name": "New School"
}
]
},
{
"name": "Kirby",
"models": [
{
"name": "Heavy"
},
{
"name": "Light"
},
{
"name": "Regular"
}
]
},
{
"name": "Hoover",
"models": [
{
"name": "Windtunnel"
},
{
"name": "Back"
},
{
"name": "Upright"
}
]
}
]
我尝试映射导入的数据,但每次我这样做来查找模型时,我最终都会返回未定义的。
我也尝试过连接 useEffect 函数,但也无法弄清楚如何正确地连接它。
就像我说的,我觉得解决方案非常简单,但我忽略了一些基本的东西。我真的只是在寻找一个看起来干净且运行良好的超级简单的解决方案。如果您需要任何其他信息来帮助我们解决此问题,请询问。
提前致谢!
这里的最佳做法是创建一个对象,在其中以 Make
名称保存模型。
const models = React.useMemo(() => {
const modelsValues = {};
makeandmodel_DATA.forEach(({ name, models }) => {
modelsValues[name] = models;
})
return modelsValues;
})
您只需要保存模型名称即可。
然后你需要访问 selected Make
模型,最后你的 Make
select 将是这样的:
{make && <FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Model</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={model}
onChange={handleModelChange}
label="Model"
>
<MenuItem value="">
<em>Choose a Model</em>
</MenuItem>
{models[make] ? models[make].map(model=> {
// Here goes your models option
return <MenuItem value="">
<em>Choose a Model</em>
</MenuItem>
}) : null
}
</Select>
</FormControl>}
也许我打错了,但如果你能给我一个沙箱,这可以更容易修复。
这是一个很好的解决方案!
我做了同样的事情,我在地图函数中添加了一个索引,为每个 MenuItem 添加了一个键,并将每个 MenuItem 的值属性和子项设置为 model.name
{make && <FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Model</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={model}
onChange={handleModelChange}
label="Model"
>
<MenuItem value="">
<em>Choose a Model</em>
</MenuItem>
{models[make]
? models[make].map((model, index) => (
<MenuItem key={index} value={model.name}>{model.name}</MenuItem>
))
: null
}
</Select>
</FormControl>}