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]}
))}
现场演示

你也能粘贴导入语句吗?这是迄今为止我得到的最完整的答案,非常感谢@所以不客气。如果行为没有文档记录,那么阅读源代码应该是最后一个解决方案,但是如果你知道在哪里阅读,它会清除很多东西。