Javascript 材质UI选择具有自定义子项的构件
我试图创建一个Javascript 材质UI选择具有自定义子项的构件,javascript,reactjs,material-ui,Javascript,Reactjs,Material Ui,我试图创建一个Select组件,其中包含一系列通过列表映射的自定义项。每个项目都有一个特定的类型,基于该类型,菜单项将有一个特定的材质UI图标。我创建了一个用于管理整个Select组件的特定组件,以及另一个用于显示每个项目、其值和图标的特定组件。问题是每当我单击其中一个项目时,onChange功能不会触发。有什么问题吗 我在附上我正在做的事情的代码 const myTypes = { TYPE_1: "Type 1", TYPE_2: "Type 2&quo
Select
组件,其中包含一系列通过列表映射的自定义项。每个项目都有一个特定的类型,基于该类型,菜单项将有一个特定的材质UI图标。我创建了一个用于管理整个Select
组件的特定组件,以及另一个用于显示每个项目、其值和图标的特定组件。问题是每当我单击其中一个项目时,onChange
功能不会触发。有什么问题吗
我在附上我正在做的事情的代码
const myTypes = {
TYPE_1: "Type 1",
TYPE_2: "Type 2",
TYPE_3: "Type 3",
};
function TypeSelect(props) {
const classes = useStyles();
const [state, setState] = useState(myTypes.TYPE_1);
const onChangeType = (e) => {
setState(e.target.value);
};
return (
<Select
id="select-type"
value={state}
onChange={onChangeType}
>
{Object.keys(myTypes).map((type) => (
<TypeSelectMenuItem
type={myTypes[type]}
key={type}
/>
))}
</Select>
);
}
function TypeSelectMenuItem({ type }) {
const renderIcon = () => {
switch (type) {
case myTypes.TYPE_1:
return <ShortTextIcon />; // Material-UI icon
case myTypes.TYPE_2:
return <SubjectIcon />; // Material-UI icon
case myTypes.TYPE_3:
return <RadioButtonCheckedIcon />; // Material-UI icon
default:
return <Fragment />;
}
};
return (
<MenuItem value={type} >
<ListItemIcon>{renderIcon()}</ListItemIcon>
<ListItemText primary={type} />
</MenuItem>
);
}
const myTypes={
类型1:“类型1”,
类型2:“类型2”,
类型3:“类型3”,
};
功能类型选择(道具){
const classes=useStyles();
const[state,setState]=useState(myTypes.TYPE_1);
const onChangeType=(e)=>{
设置状态(如目标值);
};
返回(
{Object.keys(myTypes).map((type)=>(
))}
);
}
函数类型SelectMenuItem({type}){
常数renderIcon=()=>{
开关(类型){
案例myTypes.TYPE_1:
return;//物料界面图标
案例myTypes.TYPE_2:
return;//物料界面图标
案例myTypes.TYPE_3:
return;//物料界面图标
违约:
返回;
}
};
返回(
{renderIcon()}
);
}
根据材质界面,这是如何使用菜单项
组件渲染选择
的选项:
十
二十
三十
当您希望将自定义组件而不是MenuItem
作为传递时,请选择子项。例如TypeSelectMenuItem
,您需要执行以下操作:
1.将所有道具传递给自定义项目组件
SelectInput
将克隆每个子级和其他事件处理程序作为场景后面的额外道具,因此请确保使用spread操作符将所有子级和其他事件处理程序向下传递:
consttypeselectmenuitem=(道具)=>{
返回(
{...}
);
};
{Object.keys(myTypes).map((type)=>(
{myTypes[type]}
))}
2.将选项值传递给值
道具
不要像您在这里所做的那样发明一个新的道具名称:
正确的方法是传递到值
而不是类型
道具:
原因是在内部,SelectInput
引用了props.value
,而不是您的props.type
。见和。使用道具.value
以外的任何东西都会导致意外行为
3.在自定义组件中引用数据值
,而不是值
克隆项目元素时,选择输入
值
道具以取消定义并使用数据值
道具,因此您需要在内部使用数据值
道具:
consttypeselectmenuitem=(道具)=>{
//作为子项传递时,Select.props.value的项设置为未定义。
//改用道具['data-value']。
返回(
{...}
);
};
4.将子项传递给自定义项组件以呈现选定值
SelectInput
用于呈现选定值,因此您需要确保将某些内容作为子项传递以显示:
consttypeselectmenuitem=(道具)=>{
返回(
//这是MenuItem的子项,因此不会显示为选定值
{renderIcon()}
);
};
{Object.keys(myTypes).map((type)=>(
//这是TypeSelectMenuItem的子项,因此它显示为选定值
{myTypes[type]}
))}
现场演示
你也能粘贴导入语句吗?这是迄今为止我得到的最完整的答案,非常感谢@所以不客气。如果行为没有文档记录,那么阅读源代码应该是最后一个解决方案,但是如果你知道在哪里阅读,它会清除很多东西。