选择在react材料 ui 中单击图标组件(下拉箭头)不起作用

IT技术 javascript reactjs material-ui
2021-03-29 07:24:10

下面是我的代码片段。我遇到了一个问题,当我点击 IconComponent(下拉箭头)时,选择组件没有打开。

<Select
  IconComponent={() => (
    <ExpandMore className="dropdown-arrow" />
  )}
  onChange={this.handleSelectUpdate.bind(this)}
  value={this.state.somestate}
  inputProps={{
    name: "someprops1",
    id: "someprops1"
  }}
  disabled={this.props.someprops1.length === 1}
  className="dropdown"
>
  >
  {_.map(this.props.someprops2, (item, id) => {
    return (
      <MenuItem value={item.somekey} key={id}>
        {item.somekey}
      </MenuItem>
    );
  })}
</Select>

1个回答

SelectInput.jsSelect利用)中,图标呈现如下:

<IconComponent className={classes.icon} />

通过自定义图标的方式,您忽略了SelectInput传递的 className 属性,这会阻止它正常运行。

以下是自定义图标的几个示例。第一种情况直接使用图标 ( IconComponent={ExpandMoreIcon}) 而不将其包装在另一个函数中。第二种情况显示了更接近您尝试做的事情(支持在其上指定您自己的类)。虽然classNameSelectInput当前尝试指定的唯一属性,但我认为您最好通过所有props:

const iconStyles = {
  selectIcon: {
    color: "green"
  }
};
const CustomExpandMore = withStyles(iconStyles)(
  ({ className, classes, ...rest }) => {
    return (
      <ExpandMoreIcon
        {...rest}
        className={classNames(className, classes.selectIcon)}
      />
    );
  }
);

这是完整的示例:

import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import InputLabel from "@material-ui/core/InputLabel";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import clsx from "clsx";

const styles = (theme) => ({
  root: {
    display: "flex",
    flexWrap: "wrap"
  },
  formControl: {
    margin: theme.spacing.unit,
    minWidth: 120
  },
  selectEmpty: {
    marginTop: theme.spacing.unit * 2
  }
});
const iconStyles = {
  selectIcon: {
    color: "green"
  }
};
const CustomExpandMore = withStyles(iconStyles)(
  ({ className, classes, ...rest }) => {
    return (
      <ExpandMoreIcon
        {...rest}
        className={clsx(className, classes.selectIcon)}
      />
    );
  }
);

class SimpleSelect extends React.Component {
  state = {
    age: "",
    name: "hai"
  };

  handleChange = (event) => {
    this.setState({ [event.target.name]: event.target.value });
  };

  render() {
    const { classes } = this.props;

    return (
      <form className={classes.root} autoComplete="off">
        <FormControl className={classes.formControl}>
          <InputLabel htmlFor="age-simple">Age</InputLabel>
          <Select
            value={this.state.age}
            onChange={this.handleChange}
            inputProps={{
              name: "age",
              id: "age-simple"
            }}
            IconComponent={ExpandMoreIcon}
          >
            <MenuItem value="">
              <em>None</em>
            </MenuItem>
            <MenuItem value={10}>Ten</MenuItem>
            <MenuItem value={20}>Twenty</MenuItem>
            <MenuItem value={30}>Thirty</MenuItem>
          </Select>
        </FormControl>
        <FormControl className={classes.formControl}>
          <InputLabel htmlFor="age-simple">Age</InputLabel>
          <Select
            value={this.state.age}
            onChange={this.handleChange}
            inputProps={{
              name: "age",
              id: "age-simple"
            }}
            IconComponent={CustomExpandMore}
          >
            <MenuItem value="">
              <em>None</em>
            </MenuItem>
            <MenuItem value={10}>Ten</MenuItem>
            <MenuItem value={20}>Twenty</MenuItem>
            <MenuItem value={30}>Thirty</MenuItem>
          </Select>
        </FormControl>
      </form>
    );
  }
}

SimpleSelect.propTypes = {
  classes: PropTypes.object.isRequired
};

export default withStyles(styles)(SimpleSelect);

编辑选择自定义图标

这是 Material-UI 添加到图标NativeSelect.js的样式(可以在其中导出样式以便Select.js可以重用它们):

  icon: {
    // We use a position absolute over a flexbox in order to forward the pointer events
    // to the input and to support wrapping tags..
    position: 'absolute',
    right: 0,
    top: 'calc(50% - 12px)', // Center vertically
    pointerEvents: 'none', // Don't block pointer events on the select under the icon.
    color: theme.palette.action.active,
    '&$disabled': {
      color: theme.palette.action.disabled,
    },
  },
  /* Styles applied to the icon component if the popup is open. */
  iconOpen: {
    transform: 'rotate(180deg)',
  },
  /* Styles applied to the icon component if `variant="filled"`. */
  iconFilled: {
    right: 7,
  },
  /* Styles applied to the icon component if `variant="outlined"`. */
  iconOutlined: {
    right: 7,
  },

绝对定位将图标保持在 的可点击区域内Select如果没有绝对定位,图标将导致组成 Select 的不同元素发生移动。单击图标应该继续工作的位置,但元素移动的方式导致 Select 的整体布局不再有意义。

什么是typescript版本?我得到属性 'classes' 不存在于类型 'PropsWithChildren<ConsistentWith<ConsistentWith<{}, { classes: Record<"selectIcon", string>; }>, { classes: Record<"selectIcon", string>; }> | 一致与<...>>'。
2021-06-14 07:24:10
非常感谢,这节省了很多时间。
2021-06-15 07:24:10
className={classNames(className, classes.selectIcon)} 这要求您安装 classnames 包。CodeSandbox 失败,因为缺少该依赖项。对于 MUI,最好使用 clsx,因为它已经包含在内。material-ui.com/getting-started/faq/...
2021-06-19 07:24:10
Material-UI 的 @ØysteinGrandeJaren v3(我写这个答案时的当前版本)包含了这个classnames包。他们用clsxv4替换了它我已经更新了我的示例并将沙箱更改为使用特定版本的 Material-UI 而不是“最新”,因此它不会再次以这种方式中断。
2021-06-19 07:24:10