升级到 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,已将我们的 react
和 react-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;
(这是我在 linked GitHub issue 中给出的答案的副本):
react-select
使用自己的 theme
道具进行简单样式定制,这与 mui
s 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
) 应用基本的容器样式和类名。
我已经从 @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,已将我们的 react
和 react-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;
(这是我在 linked GitHub issue 中给出的答案的副本):
react-select
使用自己的 theme
道具进行简单样式定制,这与 mui
s 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
) 应用基本的容器样式和类名。