升级到 material ui 图标 v5 破坏了反应-select

Upgrade to material ui icons v5 broke react-select

我已经从 @material-ui/icons 4.11.2 升级到 @mui/material@mui/icons-material 5.2.3

我意识到 material UI 没有直接用于 react-select 但是据我所知有一些交互。

从 Material UI 图标 v4 升级到 v5 似乎进展顺利。但是后来,我注意到所有 react-select 下拉菜单都在控制台中出现此错误并导致应用程序(即时空白屏幕)爆炸:

TypeError: theme.transitions is undefined ./node_modules/@mui/material/SvgIcon/SvgIcon.js/SvgIconRoot< node_modules/@mui/material/SvgIcon/SvgIcon.js:49

46 | display: 'inline-block',
47 | fill: 'currentColor',
48 | flexShrink: 0,
49 | transition: theme.transitions.create('fill', {
   | ^  50 |   duration: theme.transitions.duration.shorter
51 | }),
52 | fontSize: {

我一直在倾注 Material UI v4 -> v5 migration guide,已将我们的 reactreact-dom 库升级到 17.0.2,将 react-select 库升级到 5.2.1,但是此问题仍然存在。

这是我的函数组件,它包装了所有有问题的下拉菜单 select。

import React, {useState} from 'react';
import Select from 'react-select';
import {useSelector} from "react-redux";
import "./EntityChildDropdownSelector.scss"
import {selectStyles, selectTheme} from "./SelectorStyles";
import SearchIcon from '@mui/icons-material/Search';
import PropTypes from "prop-types";

/**
 EntityChildDropdownSelector for editing one attribute of an entity

 @return {*}
 @typedef EntitiesSelector{Selector} is a Redux selector that can be used to fetch the entities for this selector
 @typedef Entity{{ id:String }} is an entity having an id
 @typedef TextFormattingFunction{function} given an entity, returns it formatted as text
 @typedef ClassName{string} of attribute to edit
 @typedef ActivateFunction{function} to callback when a selection is made
 */
const EntityChildDropdownSelector = function (props) {
  const
    [isOpen, setIsOpen] = useState(false);

  // option object has id and text, must be translated back and forth value <> riek field
  const entities = useSelector(state => props.entitiesSelector(state)),
    options = entities
      .map((o) => ({value: o.id, label: props.format(o)})),
    active = !!props.active ? options.find((o) => (o.value === props.active.id)) : null;

  const
    toggleOpen = () => {
      setIsOpen(!isOpen);
    },
    onSelectChange = option => {
      toggleOpen();
      props.onActivate(option.value);
    };

  options?.length && !active && props.onActivate(options[0].value);

  return (
    <div>
      <Select
        autoFocus
        classNamePrefix="selector"
        options={options}
        value={active}
        backspaceRemovesValue={false}
        components={{DropdownIndicator: SearchIcon, IndicatorSeparator: null}}
        controlShouldRenderValue={false}
        hideSelectedOptions={false}
        isClearable={false}
        menuIsOpen
        onChange={onSelectChange}
        placeholder="Search..."
        styles={selectStyles(200)}
        theme={selectTheme}
        tabSelectsValue={false}/>
    </div>
  );
}

EntityChildDropdownSelector.propTypes = {
  entitiesSelector: PropTypes.func.isRequired,
  format: PropTypes.func,
  className: PropTypes.string,
  active: PropTypes.object,
  onActivate: PropTypes.func.isRequired,
};

export default EntityChildDropdownSelector;

也发布了这个 issue to the react-select library

(这是我在 linked GitHub issue 中给出的答案的副本):

react-select 使用自己的 theme 道具进行简单样式定制,这与 muis theme 道具冲突。

你应该用一个函数和一个原始 DropdownIndicator 的实例包装 SearchIcon 以防止道具扩散到图标组件上,但也保留正常功能:

import Select, { components } from "react-select";

const DropdownIndicator = (props) => (<components.DropdownIndicator {...props}>
  <SearchIcon />
</components.DropdownIndicator>);

<Select
  components={{
    DropdownIndicator
  }}
/>

PS:您也可以只使用 <div> 元素作为包装器(使用 props.innerProps 作为属性),但是默认的 DropdownIndicator 组件(来自 components) 应用基本的容器样式和类名。