![](/img/trans.png)
[英]material-ui <Grid item> component's children with 100% width overlaps parent
[英]Material-UI Select component with custom children item
我正在尝试创建一个Select
组件,其中包含一系列通过列表映射的自定义项目。 每个项目都有特定的类型,并且基于该类型,菜单项将具有特定的 Material-UI 图标。 我创建了一个特定组件来管理整个Select
组件和另一个特定组件来显示每个项目、它的值和它的图标。 问题是,每当我单击其中一项时,都不会触发onChange
function。 问题可能是什么?
我附上了我正在做的事情的代码。
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>
);
}
根据 Material-UI文档,这是使用MenuItem
组件呈现Select
选项的方式:
<Select value={age} onChange={handleChange}>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
当您想将自定义组件而不是MenuItem
作为Select
子项传递时。 例如TypeSelectMenuItem
,你需要做以下事情:
SelectInput
将克隆每个孩子并在场景后面附加额外的事件处理程序作为额外的道具,因此请确保使用传播运算符传递所有这些:
const TypeSelectMenuItem = (props) => {
return (
<MenuItem {...props}>
{...}
</MenuItem>
);
};
<Select value={state} onChange={onChangeType}>
{Object.keys(myTypes).map((type) => (
<TypeSelectMenuItem value={myTypes[type]} key={type}>
{myTypes[type]}
</TypeSelectMenuItem>
))}
</Select>
value
props不要像你在这里所做的那样发明一个新的道具名称:
<TypeSelectMenuItem type={myTypes[type]} key={type} />
正确的方法是传递给value
而不是type
props:
<TypeSelectMenuItem value={myTypes[type]} key={type} />
原因是因为在内部, SelectInput
引用props.value
而不是您的props.type
。 看到这个和这个。 使用props.value
以外的任何东西都会导致意外行为。
data-value
而不是value
克隆项目元素时, SelectInput
将value
props 设置为 undefined 并改用data-value
props,因此您需要在内部使用data-value
props:
const TypeSelectMenuItem = (props) => {
// when passing as children item of Select. props.value is set to undefined.
// Use props['data-value'] instead.
return (
<MenuItem {...props}>
{...}
<ListItemText primary={props["data-value"]} />
</MenuItem>
);
};
SelectInput
使用子道具来呈现选定的值,因此您需要确保将某些内容作为子项传递以显示:
const TypeSelectMenuItem = (props) => {
return (
<MenuItem {...props}>
// this is children of MenuItem, so it is not displayed as selected value
<ListItemIcon>{renderIcon()}</ListItemIcon>
<ListItemText primary={props["data-value"]} />
</MenuItem>
);
};
<Select value={state} onChange={onChangeType}>
{Object.keys(myTypes).map((type) => (
<TypeSelectMenuItem value={myTypes[type]} key={type}>
// this is children of TypeSelectMenuItem, so it is displayed as selected value
{myTypes[type]}
</TypeSelectMenuItem>
))}
</Select>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.