使用 Material Ui 和嵌套 MenuItem 的 Redux 表单不起作用

Redux Form using Material Ui with nested MenuItem not working

我是 React、Redux Form 和 Material 的新手。我想创建一个嵌套的下拉列表 select 或可以在 Redux 表单中删除的组件,类似于:

这是用于创建 select 组件的 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>
  );
};

这是我创建的代码沙箱的 link。 Material UI ReduxForm Select

除了嵌套下拉列表不更新 selector 字段外,它可以正常工作。我研究了这个并发现了这个问题 Whosebug redux form with nested lists 但没有解决方案。

任何人都可以就我缺少的东西给我建议吗?我相信我需要以某种方式将 handleSubMenuClose 函数中的事件传递回 Redux 表单,但我不知道如何做到这一点。

好吧,使用 Material UI MenuItem 不起作用,但我能够使用 redux 表单并创建一个嵌套的下拉菜单。 这是我创建的屏幕截图。它没有 open/close 面板的功能,但它仍然给用户一种嵌套下拉菜单的感觉。

这是我在 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