问题描述
我是React,Redux Form和Material的新手。我想创建一个嵌套的下拉选择器组件,该组件可以以类似于以下内容的Redux形式拖放:
这是用于创建选择组件的renderSelectField。
const renderSelectField = ({
input,label,Meta: { touched,error },children,...custom
}) => (
<SelectField
floatingLabelText={label}
errorText={touched && error}
{...input}
onChange={(event,index,value) => input.onChange(value)}
children={children}
{...custom}
/>
);
const MaterialUiForm = (props) => {
const { handleSubmit,pristine,reset,submitting,classes } = props;
return (
<form onSubmit={handleSubmit}>
<div>
<Field
name="favoriteColor"
component={renderSelectField}
label="Favorite Color"
>
<MenuItem value="ff0000" primaryText="Red" />
<MenuItem value="00ff00" primaryText="Green" />
<MenuItem value="0000ff" primaryText="Blue" />
</Field>
</div>
<div>
<Field
id='chapter'
name='chapter'
component={SelectMenu}
label='Chapter'
/>
</div>
<div>
<button type="submit" disabled={pristine || submitting}>
Submit
</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>
Clear Values
</button>
</div>
</form>
);
};
我的SelectMenu组件是
const chapterFormValues = [
{
key: "international-4",caption: "France"
},{
key: "international-5",caption: "Africa"
},{
key: "international-6",caption: "United Kingdom"
},{
key: "usa-key",caption: "north America",subMenuItems: [
{
key: "usaChapter-1",caption: "Central"
},{
key: "usaChapter-2",caption: "East"
}
]
}
];
const SelectMenu = (props) => {
const [open,setopen] = useState(false);
const handleClick = () => {
setopen((open) => !open);
};
const handleSubMenuClose = () => {
setopen((open) => !open);
};
const { label,classes } = props;
const renderMenuItems = () => {
return (
chapterFormValues !== undefined &&
chapterFormValues.map((option) => {
if (option.hasOwnProperty("subMenuItems")) {
return (
<React.Fragment>
<MenuItem onClick={handleClick} className={classes.menuItem}>
{option.caption}
{open ? <IconExpandLess /> : <IconExpandMore />}
</MenuItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<hr />
{option.subMenuItems.map((item) => (
<MenuItem
key={item.key}
className={classes.subMenuItem}
onClick={handleSubMenuClose}
>
{item.caption}
</MenuItem>
))}
</Collapse>
</React.Fragment>
);
}
return (
<MenuItem
className={classes.menuItem}
key={option.key}
value={option.caption === "None" ? "" : option.caption}
>
{option.caption}
</MenuItem>
);
})
);
};
return (
<FormControl>
<InputLabel>{label}</InputLabel>
<MuiSelect
input={<Input id={`${props.id}-select`} />}
value={props.value}
{...props.input}
{...props.custom}
>
{renderMenuItems()}
</MuiSelect>
</FormControl>
);
};
这是我创建的代码沙箱的链接。 Material UI ReduxForm Select
除了嵌套下拉列表不会更新选择器字段之外,其他方法均有效。我对此进行了研究,发现此问题Stackoverflow redux form with nested lists,但没有解决方案。
有人可以给我有关我所缺少的建议吗?我相信我需要以某种方式将handleSubMenuClose函数中的事件传递回Redux Form,但对于如何执行此操作感到困惑。
解决方法
使用Material UI MenuItem不能正常工作,但是我可以使用redux表单并创建一个嵌套下拉菜单。 这是我创建的屏幕截图。它没有打开/关闭面板的功能,但仍给用户以嵌套下拉菜单的感觉。
这是我在SelectMenu方法中更改的代码。关键是要使用Material UI Select组件和optgroup元素的本机形式。
const SelectMenu = (props) => {
const { label,classes } = props;
const renderMenuItems = () => {
return (
chapterFormValues !== undefined &&
chapterFormValues.map((option) => {
if (option.hasOwnProperty("subMenuItems")) {
return (
<React.Fragment>
<optgroup label={option.caption} className={classes.menuItem}>
{option.subMenuItems.map((item) => (
<option
key={item.key}
className={classes.subMenuItem}
>
{item.caption}
</option>
))}
</optgroup>
</React.Fragment>
);
}
return (
<option
className={classes.menuItem}
key={option.key}
value={option.caption === "None" ? "" : option.caption}
>
{option.caption === "None" ? "" : option.caption}
</option>
);
})
);
};
return (
<FormControl>
<InputLabel>{label}</InputLabel>
<Select
native
input={<Input id={`${props.id}-select`} />}
value={props.value}
{...props.input}
{...props.custom}
>
{renderMenuItems()}
</Select>
</FormControl>
);
};
有用的链接是:
HTML / CSS: Nested <options> in a <select> field?
Redux Form Material UI: Select with Nested Lists not working