跳至内容
+

v5 版本中的重大变更,第二部分:核心组件

这是一份关于 Material UI v5 中引入的重大变更以及如何从 v4 迁移的参考指南。本部分涵盖组件的变更。

Material UI v5 迁移

  1. 开始使用
  2. 重大变更第一部分:样式和主题
  3. 重大变更第二部分:组件 👈 您在这里
  4. 从 JSS 迁移
  5. 故障排除

重大变更,第二部分

Material UI v5 从 v4 引入了许多重大变更。许多这些变更可以使用 代码模组 自动解决,这些代码模组在 主迁移指南 中描述。

以下文档列出了 v5 中与组件相关的所有重大变更以及如何解决这些变更。

如果您尚未这样做,请务必查看 v5 版本中的重大变更第一部分:样式和主题,以继续迁移过程。

由于核心组件使用 Emotion 作为其样式引擎,因此 Emotion 使用的 props 不会被拦截。以下代码片段中的 as prop 将不会传播到 SomeOtherComponent

<MuiComponent component={SomeOtherComponent} as="button" />

AppBar

修复 z-index 问题

移除 position 为 static 和 relative 时的 z-index。这避免了堆叠上下文的创建和渲染问题。

替换暗黑模式下的 color prop

color prop 在暗黑模式下不再有任何效果。应用栏使用 elevation 所需的背景颜色,以遵循 Material Design 指南。使用 enableColorOnDark 恢复 v4 的行为。

<AppBar enableColorOnDark />

Alert

✅ 更新导入

将组件从 lab 移动到 core。该组件现在是稳定的。

-import Alert from '@mui/lab/Alert';
-import AlertTitle from '@mui/lab/AlertTitle';
+import Alert from '@mui/material/Alert';
+import AlertTitle from '@mui/material/AlertTitle';

Autocomplete

✅ 更新导入

将组件从 lab 移动到 core。该组件现在是稳定的。

-import Autocomplete from '@mui/lab/Autocomplete';
-import useAutocomplete  from '@mui/lab/useAutocomplete';
+import Autocomplete from '@mui/material/Autocomplete';
+import useAutocomplete from '@mui/material/useAutocomplete';

移除 debug prop

移除 debug prop。有几个更简单的替代方案:open={true},Chrome devtools "模拟焦点",或 React devtools prop setter。

更新 renderOption

renderOption 现在应该返回选项的完整 DOM 结构。这使得自定义更容易。您可以使用以下方法从更改中恢复

 <Autocomplete
-  renderOption={(option, { selected }) => (
-    <React.Fragment>
+  renderOption={(props, option, { selected }) => (
+    <li {...props}>
       <Checkbox
         icon={icon}
         checkedIcon={checkedIcon}
         style={{ marginRight: 8 }}
         checked={selected}
       />
       {option.title}
-    </React.Fragment>
+    </li>
   )}
 />

✅ 将 closeIcon 重命名为 clearIcon

closeIcon prop 重命名为 clearIcon 以避免混淆。

-<Autocomplete closeIcon={defaultClearIcon} />
+<Autocomplete clearIcon={defaultClearIcon} />

重命名 reason 参数

为了保持一致性,onChangeonClose 中 reason 参数的以下值被重命名

  1. create-option 改为 createOption
  2. select-option 改为 selectOption
  3. remove-option 改为 removeOption

更改使用 [data-focus="true"] 的 CSS 规则以使用 .Mui-focuseddata-focus 属性不再在聚焦的选项上设置;而是使用全局类名。

-'.MuiAutocomplete-option[data-focus="true"]': {
+'.MuiAutocomplete-option.Mui-focused': {

✅ 重命名 getOptionSelected

getOptionSelected 重命名为 isOptionEqualToValue 以更好地描述其目的。

 <Autocomplete
-  getOptionSelected={(option, value) => option.title === value.title}
+  isOptionEqualToValue={(option, value) => option.title === value.title}

Avatar

✅ 重命名 circle

circle 重命名为 circular 以保持一致性

-<Avatar variant="circle">
-<Avatar classes={{ circle: 'className' }}>
+<Avatar variant="circular">
+<Avatar classes={{ circular: 'className' }}>

由于 circular 是默认值,因此可以删除 variant prop

-<Avatar variant="circle">
+<Avatar>

✅ 更新 AvatarGroup 导入

将 AvatarGroup 从 lab 移动到 core。

-import AvatarGroup from '@mui/lab/AvatarGroup';
+import AvatarGroup from '@mui/material/AvatarGroup';

Badge

✅ 重命名 circle 和 rectangle

circle 重命名为 circular,将 rectangle 重命名为 rectangular 以保持一致性。

-<Badge overlap="circle">
-<Badge overlap="rectangle">
+<Badge overlap="circular">
+<Badge overlap="rectangular">
 <Badge classes={{
-  anchorOriginTopRightRectangle: 'className',
-  anchorOriginBottomRightRectangle: 'className',
-  anchorOriginTopLeftRectangle: 'className',
-  anchorOriginBottomLeftRectangle: 'className',
-  anchorOriginTopRightCircle: 'className',
-  anchorOriginBottomRightCircle: 'className',
-  anchorOriginTopLeftCircle: 'className',
+  anchorOriginTopRightRectangular: 'className',
+  anchorOriginBottomRightRectangular: 'className',
+  anchorOriginTopLeftRectangular: 'className',
+  anchorOriginBottomLeftRectangular: 'className',
+  anchorOriginTopRightCircular: 'className',
+  anchorOriginBottomRightCircular: 'className',
+  anchorOriginTopLeftCircular: 'className',
 }}>

BottomNavigation

更新事件类型 (TypeScript)

onChange 中的 event 现在类型为 React.SyntheticEvent 而不是 React.ChangeEvent

-<BottomNavigation onChange={(event: React.ChangeEvent<{}>) => {}} />
+<BottomNavigation onChange={(event: React.SyntheticEvent) => {}} />

BottomNavigationAction

移除 span 和 wrapper

移除包裹 children 的 span 元素。也移除了 wrapper classKey。

您可以在 此 GitHub pull request 中找到有关此更改的更多详细信息。

 <button class="MuiBottomNavigationAction-root">
-  <span class="MuiBottomNavigationAction-wrapper">
     {icon}
     <span class="MuiBottomNavigationAction-label">
       {label}
     </span>
-  </span>
 </button>

Box

✅ 更新 borderRadius prop 值

borderRadius 系统 prop 值转换已更改。

如果它接收到一个数字,它会将该值与 theme.shape.borderRadius 值相乘。

使用字符串来提供显式的 px 值。

-<Box borderRadius="borderRadius">
+<Box borderRadius={1}>
-<Box borderRadius={16}>
+<Box borderRadius="16px">

✅ 应用 sx API

Box 系统 props 在 v5 中有一个可选的替代 API,使用 sx prop。

查看 MUI System 文档以了解更多关于 此 API 的权衡

<Box border="1px dashed grey" p={[2, 3, 4]} m={2}>
<Box sx={{ border: "1px dashed grey", p: [2, 3, 4], m: 2 }}>

✅ 重命名 CSS 属性

以下属性已被重命名,因为它们被 CSS 规范视为已弃用的 CSS 属性

  1. gridGap 改为 gap
  2. gridColumnGap 改为 columnGap
  3. gridRowGap 改为 rowGap
-<Box gridGap={1}>
-<Box gridColumnGap={2}>
-<Box gridRowGap={3}>
+<Box gap={1}>
+<Box columnGap={2}>
+<Box rowGap={3}>

移除 clone prop

clone prop 已被移除,因为如果子组件是 Material UI 组件,则可以通过直接将 sx prop 应用于子组件来获得其行为。

-<Box sx={{ border: '1px dashed grey' }} clone>
-  <Button>Save</Button>
-</Box>
+<Button sx={{ border: '1px dashed grey' }}>Save</Button>

使用 sx 替换 render prop

移除传递 render prop 的能力,因为如果子组件是 Material UI 组件,则可以通过直接将 sx prop 应用于子组件来获得其行为。

-<Box sx={{ border: '1px dashed grey' }}>
-  {(props) => <Button {...props}>Save</Button>}
-</Box>
+<Button sx={{ border: '1px dashed grey' }}>Save</Button>

对于非 Material UI 组件,请使用 component prop。

-<Box sx={{ border: '1px dashed grey' }}>
-  {(props) => <button {...props}>Save</button>}
-</Box>
+<Box component="button" sx={{ border: '1px dashed grey' }}>Save</Box>

Button

✅ 移除默认 color prop

按钮 color prop 现在默认为 "primary",并且移除了 "default"。这使得按钮更接近 Material Design 指南并简化了 API。

-<Button color="default">
+<Button>

移除 span 和 label

包裹 children 的 span 元素已被移除。label classKey 也被移除。

您可以在 此 GitHub pull request 中找到有关此更改的更多详细信息,它过去对于 iOS 是必要的。

 <button class="MuiButton-root">
-  <span class="MuiButton-label">
     children
-  </span>
 </button>

Chip

✅ 将 default 重命名为 filled

default variant 重命名为 filled 以保持一致性。

由于 filled 是默认值,因此可以删除 variant prop

-<Chip variant="default">
+<Chip>

Checkbox

默认设置为 "primary"

复选框 color prop 现在默认为 "primary"。要继续使用 "secondary" 颜色,您必须明确指出 secondary。这使复选框更接近 Material Design 指南。

-<Checkbox />
+<Checkbox color="secondary" />

更新 CSS 类名

该组件不再具有 .MuiIconButton-root.MuiIconButton-label 类名。

改为定位 .MuiButtonBase-root

-<span class="MuiIconButton-root MuiButtonBase-root MuiCheckbox-root PrivateSwitchBase-root">
-  <span class="MuiIconButton-label">
-    <input class="PrivateSwitchBase-input">
+<span class="MuiButtonBase-root MuiCheckbox-root PrivateSwitchBase-root">
+  <span class="PrivateSwitchBase-input">

CircularProgress

✅ 将 static 重命名为 determinate

static variant 已被重命名为 determinate,并且先前 determinate 的外观已被 static 的外观所取代。

这是 Material Design 的一个例外,已从规范中移除。

-<CircularProgress variant="static" classes={{ static: 'className' }} />
+<CircularProgress variant="determinate" classes={{ determinate: 'className' }} />

Collapse

✅ 重命名 collapsedHeight prop

collapsedHeight prop 已重命名为 collapsedSize 以支持水平方向。

-<Collapse collapsedHeight={40}>
+<Collapse collapsedSize={40}>

classes.container key 已更改以匹配其他组件的约定。

-<Collapse classes={{ container: 'collapse' }}>
+<Collapse classes={{ root: 'collapse' }}>

CssBaseline

更新 styled-engine

该组件已迁移为使用 @mui/styled-engine (emotionstyled-components) 而不是 jss

在为其定义样式覆盖时,您应该移除 @global key。您也可以开始使用 CSS 模板语法而不是 JavaScript 对象语法。

 const theme = createTheme({
   components: {
     MuiCssBaseline: {
-      styleOverrides: {
-        '@global': {
-          html: {
-            WebkitFontSmoothing: 'auto',
-          },
-        },
-      },
+      styleOverrides: `
+        html {
+          -webkit-font-smoothing: auto;
+        }
+      `
     },
   },
 });

更新 body 字体大小

body 字体大小已从 theme.typography.body2 (0.875rem) 更改为 theme.typography.body1 (1rem)。要返回到先前的大小,您可以在主题中覆盖它

const theme = createMuiTheme({
  components: {
    MuiCssBaseline: {
      styleOverrides: {
        body: {
          fontSize: '0.875rem',
          lineHeight: 1.43,
          letterSpacing: '0.01071em',
        },
      },
    },
  },
});

Dialog

✅ 更新 transition props

on* transition props 已被移除。请改用 TransitionProps

  <Dialog
-  onEnter={onEnter}
-  onEntered={onEntered}
-  onEntering={onEntering}
-  onExit={onExit}
-  onExited={onExited}
-  onExiting={onExiting}
+  TransitionProps={{
+    onEnter,
+    onEntered,
+    onEntering,
+    onExit,
+    onExited,
+    onExiting,
+  }}
  >

✅ 移除 disableBackdropClick prop

移除 disableBackdropClick prop,因为它​​是多余的。

reason === 'backdropClick' 时,忽略来自 onClose 的 close 事件。

  <Dialog
-  disableBackdropClick
-  onClose={handleClose}
+  onClose={(event, reason) => {
+    if (reason !== 'backdropClick') {
+      handleClose(event, reason);
+    }
+  }}
  />

移除 withMobileDialog 组件

移除 withMobileDialog 高阶组件。

hook API 允许更简单和更灵活的解决方案

-import withMobileDialog from '@mui/material/withMobileDialog';
+import { useTheme, useMediaQuery } from '@mui/material';

 function ResponsiveDialog(props) {
-  const { fullScreen } = props;
+  const theme = useTheme();
+  const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
   const [open, setOpen] = React.useState(false);

 // ...

-export default withMobileDialog()(ResponsiveDialog);
+export default ResponsiveDialog;

✅ 移除 disableTypography prop

扁平化 DialogTitle DOM 结构并移除 disableTypography prop。

-<DialogTitle disableTypography>
-  <Typography variant="h4" component="h2">
+<DialogTitle>
+  <Typography variant="h4" component="span">
      My header
   </Typography>

Divider

将 background-color 替换为 border-color

使用 border-color 而不是 background-color。这可以防止在缩放屏幕上高度不一致。

如果您自定义了边框的颜色,则需要更新 CSS 属性覆盖

 .MuiDivider-root {
-  background-color: #f00;
+  border-color: #f00;
 }

支持 "middle" variant 与 "vertical" orientation

在 v4 中,使用 orientation="vertical"variant="middle" 会在组件中添加 16px 的左右边距。在 v5 中,为了避免组件上的固定间距,移除了此边距。

 const theme = createTheme({
  components: {
   MuiDivider: {
+     styleOverrides: {
+       root: ({ ownerState, theme }) => ({
+         ...(ownerState.orientation === 'vertical' && ownerState.variant === 'middle' && {
+           marginLeft: theme.spacing(2),
+           marginRight: theme.spacing(2),
+         }),
+       })
+     }
    },
  },
 });

ExpansionPanel

✅ 重命名组件

ExpansionPanel 组件重命名为 Accordion 以使用更常见的命名约定

-import ExpansionPanel from '@mui/material/ExpansionPanel';
-import ExpansionPanelSummary from '@mui/material/ExpansionPanelSummary';
-import ExpansionPanelDetails from '@mui/material/ExpansionPanelDetails';
-import ExpansionPanelActions from '@mui/material/ExpansionPanelActions';
+import Accordion from '@mui/material/Accordion';
+import AccordionSummary from '@mui/material/AccordionSummary';
+import AccordionDetails from '@mui/material/AccordionDetails';
+import AccordionActions from '@mui/material/AccordionActions';

-<ExpansionPanel>
+<Accordion>
-  <ExpansionPanelSummary>
+  <AccordionSummary>
      <Typography>Location</Typography>
      <Typography>Select trip destination</Typography>
-  </ExpansionPanelSummary>
+  </AccordionSummary>
-  <ExpansionPanelDetails>
+  <AccordionDetails>
      <Chip label="Barbados" onDelete={() => {}} />
      <Typography variant="caption">Select your destination of choice</Typography>
-  </ExpansionPanelDetails>
+  </AccordionDetails>
    <Divider />
-  <ExpansionPanelActions>
+  <AccordionActions>
      <Button size="small">Cancel</Button>
      <Button size="small">Save</Button>
-  </ExpansionPanelActions>
+  </AccordionActions>
-</ExpansionPanel>
+</Accordion>

更新事件类型 (TypeScript)

onChange 中的 event 现在类型为 React.SyntheticEvent 而不是 React.ChangeEvent

-<Accordion onChange={(event: React.ChangeEvent<{}>, expanded: boolean) => {}} />
+<Accordion onChange={(event: React.SyntheticEvent, expanded: boolean) => {}} />

ExpansionPanelDetails

移除 display: flex

AccordionDetails (以前的 ExpansionPanelDetails) 中移除 display: flex,因为它太固执己见 - 大多数开发人员期望 display: block

ExpansionPanelSummary

将 focused 重命名为 focusVisible

focused 重命名为 focusVisible 以保持一致性

 <AccordionSummary
   classes={{
-    focused: 'custom-focus-visible-classname',
+    focusVisible: 'custom-focus-visible-classname',
   }}
 />

移除 IconButtonProps prop

AccordionSummary (以前的 ExpansionPanelSummary) 中移除 IconButtonProps prop。

该组件渲染一个 <div> 元素而不是 IconButton,因此不再需要该 prop。

Fab

✅ 将 round 重命名为 circular

-<Fab variant="round">
+<Fab variant="circular">

移除 span 和 label

包裹 children 的 span 元素已被移除。label classKey 也被移除。

您可以在 此 GitHub pull request 中找到有关此更改的更多详细信息,它过去对于 iOS 是必要的。

 <button class="MuiFab-root">
-  <span class="MuiFab-label">
     {children}
-  </span>
 </button>

FormControl

✅ 更新默认 variant

将默认 variant 从 standard 更改为 outlined

standard 已从 Material Design 指南中移除。

-<FormControl value="Standard" />
-<FormControl value="Outlined" variant="outlined" />
+<FormControl value="Standard" variant="standard" />
+<FormControl value="Outlined" />

FormControlLabel

添加 required label prop

label prop 现在是必需的。如果您正在使用没有 labelFormControlLabel,您可以将其替换为仅 control prop 的值。

-<FormControlLabel control={<Checkbox />} />
+<Checkbox />

Grid

✅ 重命名 justify prop

justify prop 重命名为 justifyContent 以与 CSS 属性名称对齐。

-<Grid justify="center">
+<Grid justifyContent="center">

✅ 移除 align 和 justify props 和 classes

props alignItemsalignContentjustifyContent - 以及它们的类和样式覆盖 key - 已被移除

"align-items-xs-center"、"align-items-xs-flex-start"、"align-items-xs-flex-end"、"align-items-xs-baseline"、"align-content-xs-center"、"align-content-xs-flex-start"、"align-content-xs-flex-end"、"align-content-xs-space-between"、"align-content-xs-space-around"、"justify-content-xs-center"、"justify-content-xs-flex-end"、"justify-content-xs-space-between"、"justify-content-xs-space-around" 和 "justify-content-xs-space-evenly"。

这些 props 现在被认为是 MUI System 的一部分,而不是 Grid 组件本身。

如果您仍然希望为它们添加覆盖,您可以使用 回调作为 styleOverrides 中的值

 const theme = createTheme({
   components: {
     MuiGrid: {
-      styleOverrides: {
-        'align-items-xs-flex-end': {
-          marginTop: 20,
-        },
-      },
+      styleOverrides: ({ ownerState }) => ({
+        ...ownerState.alignItems === 'flex-end' && {
+          marginTop: 20,
+        },
+      }),
     },
   },
 });

更改负边距

负边距仅适用于网格容器的顶部和左侧。如果您需要在所有侧面都有负边距,我们建议使用新的 Grid v2 代替

- import Grid from '@mui/material/Grid';
+ import Grid from '@mui/material/Grid2';

要了解有关 Grid2 的更多信息,请查看 Grid2 组件文档升级指南

GridList

✅ 重命名 GridList 组件

GridList 组件重命名为 ImageList 以与当前的 Material Design 命名对齐。

重命名 GridList props

  • 将 GridList spacing prop 重命名为 gap 以与 CSS 属性对齐。
  • 将 GridList cellHeight prop 重命名为 rowHeight
  • variant prop 添加到 GridList。
  • 将 GridListItemBar actionPosition prop 重命名为 position。(另请注意相关的类名更改。)

使用 CSS object-fit

使用 CSS object-fit。对于 IE 11 支持,要么使用 polyfill,例如 此 npm 包,要么继续使用 v4 组件。

-import GridList from '@mui/material/GridList';
-import GridListTile from '@mui/material/GridListTile';
-import GridListTileBar from '@mui/material/GridListTileBar';
+import ImageList from '@mui/material/ImageList';
+import ImageListItem from '@mui/material/ImageListItem';
+import ImageListItemBar from '@mui/material/ImageListItemBar';

-<GridList spacing={8} cellHeight={200}>
-  <GridListTile>
+<ImageList gap={8} rowHeight={200}>
+  <ImageListItem>
    <img src="file.jpg" alt="Image title" />
-    <GridListTileBar
+    <ImageListItemBar
      title="Title"
      subtitle="Subtitle"
    />
-  </GridListTile>
-</GridList>
+  </ImageListItem>
+</ImageList>

Hidden

替换已弃用的组件

此组件已弃用,因为其功能可以使用 sx prop 或 useMediaQuery hook 创建。

使用 sx prop 替换 implementation="css"

-<Hidden implementation="css" xlUp><Paper /></Hidden>
-<Hidden implementation="css" xlUp><button /></Hidden>
+<Paper sx={{ display: { xl: 'none', xs: 'block' } }} />
+<Box component="button" sx={{ display: { xl: 'none', xs: 'block' } }} />
-<Hidden implementation="css" mdDown><Paper /></Hidden>
-<Hidden implementation="css" mdDown><button /></Hidden>
+<Paper sx={{ display: { xs: 'none', md: 'block' } }} />
+<Box component="button" sx={{ display: { xs: 'none', md: 'block' } }} />

使用 useMediaQuery hook 替换 implementation="js"

-<Hidden implementation="js" xlUp><Paper /></Hidden>
+const hidden = useMediaQuery(theme => theme.breakpoints.up('xl'));
+return hidden ? null : <Paper />;

Icon

移除 fontSize="default"

fontSize 的默认值已从 default 更改为 medium 以保持一致性。在不太可能的情况下,您正在使用值 default,则可以删除该 prop

-<Icon fontSize="default">icon-name</Icon>
+<Icon>icon-name</Icon>

IconButton

✅ 更新 size prop

默认大小的 padding 已减少到 8px,使其降至 40px。

对于旧的默认大小 48px,请使用 size="large"

进行此更改是为了更好地匹配 Google 的产品,当时 Material Design 停止记录图标按钮模式。

- <IconButton>
+ <IconButton size="large">

移除 span 和 label

包裹 children 的 span 元素已被移除。label classKey 也被移除。

您可以在 此 GitHub pull request 中找到有关此更改的更多详细信息,它过去对于 iOS 是必要的。

 <button class="MuiIconButton-root">
-  <span class="MuiIconButton-label">
     <svg />
-  </span>
 </button>

✅ 更新默认 underline prop

默认 underline prop 从 "hover" 更改为 "always"

要重新创建 v4 的行为,请在主题中应用 defaultProps

createTheme({
  components: {
    MuiLink: {
      defaultProps: {
        underline: 'hover',
      },
    },
  },
});

✅ 更新 transition props

on* transition props 已被移除。请改用 TransitionProps

 <Menu
-  onEnter={onEnter}
-  onEntered={onEntered}
-  onEntering={onEntering}
-  onExit={onExit}
-  onExited={onExited}
-  onExiting={onExiting}
+  TransitionProps={{
+    onEnter,
+    onEntered,
+    onEntering,
+    onExit,
+    onExited,
+    onExiting,
+  }}
 >

更改默认 anchorOrigin.vertical 值

更改 anchorOrigin.vertical 的默认值以遵循 Material Design 指南。

菜单现在显示在锚点下方而不是上方。

您可以使用以下方法恢复以前的行为

 <Menu
+  anchorOrigin={{
+    vertical: 'top',
+    horizontal: 'left',
+  }}

更新 CSS 类名

MenuItem 组件继承 ButtonBase 组件而不是 ListItem

与 "MuiListItem-*" 相关的类名已被移除,并且主题化 ListItem 不再对 MenuItem 产生影响。

-<li className="MuiButtonBase-root MuiMenuItem-root MuiListItem-root">
+<li className="MuiButtonBase-root MuiMenuItem-root">

替换 listItemClasses prop

prop listItemClasses 已移除,请改用 classes

-<MenuItem listItemClasses={{...}}>
+<MenuItem classes={{...}}>

阅读有关 MenuItem CSS API 的更多信息。

✅ 移除 disableBackdropClick prop

移除 disableBackdropClick prop,因为它​​是多余的。

使用 onClosereason === 'backdropClick' 代替。

 <Modal
-  disableBackdropClick
-  onClose={handleClose}
+  onClose={(event, reason) => {
+    if (reason !== 'backdropClick') {
+      handleClose(event, reason);
+    }
+  }}
 />

✅ 移除 onEscapeKeyDown prop

移除 onEscapeKeyDown prop,因为它​​是多余的。

使用 onClosereason === "escapeKeyDown" 代替。

 <Modal
-  onEscapeKeyDown={handleEscapeKeyDown}
+  onClose={(event, reason) => {
+    if (reason === 'escapeKeyDown') {
+      handleEscapeKeyDown(event);
+    }
+  }}
 />

移除 onRendered prop

移除 onRendered prop。

根据您的用例,您可以对子元素使用 回调 ref,或者在子组件中使用 effect hook。

NativeSelect

移除 selectMenu slot

selectMenu slot 合并到 select 中。selectMenu slot 是多余的。

root slot 不再应用于 select,而是应用于 root。

-<NativeSelect classes={{ root: 'class1', select: 'class2', selectMenu: 'class3' }} />
+<NativeSelect classes={{ select: 'class1 class2 class3' }} />

OutlinedInput

替换 labelWidth prop

移除 labelWidth prop。

label prop 现在实现了相同的目的,使用 CSS 布局而不是 JavaScript 测量来渲染 outlined 中的间隙。

-<OutlinedInput labelWidth={20} />
+<OutlinedInput label="First Name" />

Paper

更改暗黑模式背景不透明度

根据暗黑模式下的 elevation 更改背景不透明度。

此更改是为了更好地符合 Material Design 指南。

您可以在主题中恢复它

 const theme = createTheme({
   components: {
     MuiPaper: {
+      styleOverrides: { root: { backgroundImage: 'unset' } },
     },
   },
 });

Pagination

✅ 更新导入

将组件从 lab 移动到 core。

该组件现在是稳定的。

-import Pagination from '@mui/lab/Pagination';
-import PaginationItem from '@mui/lab/PaginationItem';
-import { usePagination } from '@mui/lab/Pagination';
+import Pagination from '@mui/material/Pagination';
+import PaginationItem from '@mui/material/PaginationItem';
+import usePagination from '@mui/material/usePagination';

✅ 将 round 重命名为 circular

-<Pagination shape="round">
-<PaginationItem shape="round">
+<Pagination shape="circular">
+<PaginationItem shape="circular">

Popover

✅ 更新 transition props

on* transition props 已被移除。

请改用 TransitionProps

  <Popover
-  onEnter={onEnter}
-  onEntered={onEntered}
-  onEntering={onEntering}
-  onExit={onExit}
-  onExited={onExited}
-  onExiting={onExiting}
+  TransitionProps={{
+    onEnter,
+    onEntered,
+    onEntering,
+    onExit,
+    onExited,
+    onExiting,
+  }}
  >

移除 getContentAnchorEl prop

移除 getContentAnchorEl prop 以简化定位逻辑。

Popper

从 v1 升级到 v2

Popper.js 从 v1 升级到 v2。

CSS 前缀已更改

  popper: {
    zIndex: 1,
-  '&[x-placement*="bottom"] .arrow': {
+  '&[data-popper-placement*="bottom"] .arrow': {

方法名称已更改

-popperRef.current.scheduleUpdate()
+popperRef.current.update()
-popperRef.current.update()
+popperRef.current.forceUpdate()

Modifiers API 也已进行了重大更改,无法在此处完全涵盖。

阅读 Popper.js 迁移指南 以获取完整详细信息。

Portal

移除 onRendered prop

移除 onRendered prop。

根据您的用例,您可以对子元素使用 回调 ref,或者在子组件中使用 effect hook。

Radio

更新默认 color prop

单选按钮 color prop 现在默认为 "primary"。

要继续使用 "secondary" 颜色,您必须明确指出 secondary

这使单选按钮更接近 Material Design 指南。

-<Radio />
+<Radio color="secondary" />

更新 CSS 类

此组件不再具有类名 .MuiIconButton-root.MuiIconButton-label

改为定位 .MuiButtonBase-root

- <span class="MuiIconButton-root MuiButtonBase-root MuiRadio-root PrivateSwitchBase-root">
-   <span class="MuiIconButton-label">
-     <input class="PrivateSwitchBase-input">
+ <span class="MuiButtonBase-root MuiRadio-root PrivateSwitchBase-root">
+   <span class="PrivateSwitchBase-input">

Rating

✅ 更新导入

将组件从 lab 移动到 core。

该组件现在是稳定的。

-import Rating from '@mui/lab/Rating';
+import Rating from '@mui/material/Rating';

更改默认空图标

更改默认空图标以提高可访问性。

如果您有自定义 icon prop 但没有 emptyIcon prop,您可以使用以下方法恢复以前的行为

 <Rating
   icon={customIcon}
+  emptyIcon={null}
 />

重命名 visuallyhidden

visuallyhidden 重命名为 visuallyHidden 以保持一致性

  <Rating
    classes={{
-    visuallyhidden: 'custom-visually-hidden-classname',
+    visuallyHidden: 'custom-visually-hidden-classname',
    }}
  />

RootRef

移除 component

此组件已被移除。

您可以通过 ref prop 获取对我们的组件的底层 DOM 节点的引用。

该组件依赖于 ReactDOM.findDOMNode,它在 React.StrictMode 中已被弃用

-<RootRef rootRef={ref}>
-  <Button />
-</RootRef>
+<Button ref={ref} />

Select

✅ 更新默认 variant

将默认 variant 从 standard 更改为 outlined

standard 已从 Material Design 指南中移除。

如果您正在使用表单控件组件组合 Select,您只需要更新 FormControl - select 从其上下文中继承 variant。

-<Select value="Standard" />
-<Select value="Outlined" variant="outlined" />
+<Select value="Standard" variant="standard" />
+<Select value="Outlined" />

替换 labelWidth prop

移除 labelWidth prop。

label prop 现在实现了相同的目的,使用 CSS 布局而不是 JavaScript 测量来渲染 outlined variant 中的间隙。

TextField 已经默认处理了这一点。

-<Select variant="outlined" labelWidth={20} />
+<Select variant="outlined" label="Gender" />

移除 selectMenu slot

selectMenu slot 合并到 select 中。selectMenu slot 是多余的。

root slot 不再应用于 select,而是应用于 root。

-<Select classes={{ root: 'class1', select: 'class2', selectMenu: 'class3' }} />
+<Select classes={{ select: 'class1 class2 class3' }} />

更新事件类型 (TypeScript)

onChange 中的 event 现在类型为 SelectChangeEvent<T> 而不是 React.ChangeEvent

+ import Select, { SelectChangeEvent } from '@mui/material/Select';

-<Select onChange={(event: React.SyntheticEvent, value: unknown) => {}} />
+<Select onChange={(event: SelectChangeEvent<T>, child: React.ReactNode) => {}} />

这是必要的,以防止覆盖导致更改的事件的 event.target

Skeleton

✅ 更新导入

将组件从 lab 移动到 core。

该组件现在是稳定的。

-import Skeleton from '@mui/lab/Skeleton';
+import Skeleton from '@mui/material/Skeleton';

✅ 重命名 circle 和 rect

circle 重命名为 circular,将 rect 重命名为 rectangular 以保持一致性

-<Skeleton variant="circle" />
-<Skeleton variant="rect" />
-<Skeleton classes={{ circle: 'custom-circle-classname', rect: 'custom-rect-classname',  }} />
+<Skeleton variant="circular" />
+<Skeleton variant="rectangular" />
+<Skeleton classes={{ circular: 'custom-circle-classname', rectangular: 'custom-rect-classname',  }} />

Slider

更新事件类型 (TypeScript)

onChange 中的 event 现在类型为 React.SyntheticEvent 而不是 React.ChangeEvent

-<Slider onChange={(event: React.SyntheticEvent, value: unknown) => {}} />
+<Slider onChange={(event: Event, value: unknown) => {}} />

这是必要的,以防止覆盖导致更改的事件的 event.target

替换 ValueLabelComponent 和 ThumbComponent props

ValueLabelComponentThumbComponent props 现在是 components prop 的一部分。

  <Slider
-  ValueLabelComponent={CustomValueLabel}
-  ThumbComponent={CustomThumb}
+  components={{
+    ValueLabel: CustomValueLabel,
+    Thumb: CustomThumb,
+  }}
  />

重构 CSS

重新设计 CSS 以匹配最新的 Material Design 指南,并使自定义样式更直观。 请参阅文档

您可以使用 size="small" prop 降低滑块的密度,使其更接近 v4。

Snackbar

更新默认定位

通知现在在大屏幕上显示在左下角。

这更好地匹配了 Gmail、Google Keep、material.io 等的行为。

您可以使用以下方法恢复 v4 行为

-<Snackbar />
+<Snackbar anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} />

✅ 更新 transition props

on* transition props 已被移除。

请改用 TransitionProps

 <Snackbar
-  onEnter={onEnter}
-  onEntered={onEntered}
-  onEntering={onEntering}
-  onExit={onExit}
-  onExited={onExited}
-  onExiting={onExiting}
+  TransitionProps={{
+    onEnter,
+    onEntered,
+    onEntering,
+    onExit,
+    onExited,
+    onExiting,
+  }}
 >

SpeedDial

✅ 更新导入

将组件从 lab 移动到 core。

该组件现在是稳定的。

-import SpeedDial from '@mui/lab/SpeedDial';
-import SpeedDialAction from '@mui/lab/SpeedDialAction';
-import SpeedDialIcon from '@mui/lab/SpeedDialIcon';
+import SpeedDial from '@mui/material/SpeedDial';
+import SpeedDialAction from '@mui/material/SpeedDialAction';
+import SpeedDialIcon from '@mui/material/SpeedDialIcon';

Stepper

更新组件结构

根组件 Paper 已被替换为 <div>

Stepper 不再具有 elevation,并且不再从 Paper 继承 props。此更改旨在鼓励组合。

+<Paper square elevation={2}>
-  <Stepper elevation={2}>
+  <Stepper>
      <Step>
        <StepLabel>Hello world</StepLabel>
      </Step>
    </Stepper>
+<Paper>

移除内置 padding

内置的 24px padding 已被移除。

要保持不变,请添加以下内容

-<Stepper>
+<Stepper style={{ padding: 24 }}>
    <Step>
      <StepLabel>Hello world</StepLabel>
    </Step>
  </Stepper>

SvgIcon

移除 fontSize="default"

fontSize 的默认值已从 default 更改为 medium 以保持一致性。

在不太可能的情况下,您正在使用值 default,则可以删除该 prop

-<SvgIcon fontSize="default">
+<SvgIcon>
   <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />
 </SvgIcon>

Switch

移除第二个 onChange 参数

来自 onChange 的第二个参数已被弃用。

您可以通过访问 event.target.checked 来拉取 checked 状态。

 function MySwitch() {
-  const handleChange = (event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => {
+  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+    const checked = event.target.checked;
   };

   return <Switch onChange={handleChange} />;
 }

更新默认 color prop

color prop 现在默认为 "primary"。

要继续使用 "secondary" 颜色,您必须明确指出 secondary

这使 Switch 更接近 Material Design 指南。

-<Switch />
+<Switch color="secondary" />

更新 CSS 类

此组件不再具有 .MuiIconButton-root.MuiIconButton-label

改为定位 .MuiButtonBase-root

  <span class="MuiSwitch-root">
-  <span class="MuiIconButton-root MuiButtonBase-root MuiSwitch-switchBase PrivateSwitchBase-root">
-    <span class="MuiIconButton-label">
-      <input class="MuiSwitch-input PrivateSwitchBase-input">
+  <span class="MuiButtonBase-root MuiSwitch-switchBase PrivateSwitchBase-root">
+    <span class="MuiSwitch-input PrivateSwitchBase-input">

Table

重命名默认 padding prop 值

padding prop 的 default 值重命名为 normal

-<Table padding="default" />
-<TableCell padding="default" />
+<Table padding="normal" />
+<TableCell padding="normal" />

TablePagination

使用 getItemAriaLabel prop 自定义标签

表格分页操作标签的自定义必须使用 getItemAriaLabel prop 完成。

这提高了与 Pagination 组件的一致性。

  <TablePagination
-  backIconButtonText="Back"
-  nextIconButtonText="Next"
+  getItemAriaLabel={…}

✅ 重命名 onChangeRowsPerPage 和 onChangePage

onChangeRowsPerPage 重命名为 onRowsPerPageChange,将 onChangePage 重命名为 onPageChange 以保持 API 一致性。

  <TablePagination
-  onChangeRowsPerPage={()=>{}}
-  onChangePage={()=>{}}
+  onRowsPerPageChange={()=>{}}
+  onPageChange={()=>{}}

分离 label 类

分离不同表格分页标签的类。

  <TablePagination
-  classes={{ caption: 'foo' }}
+  classes={{ selectLabel: 'foo', displayedRows: 'foo' }}
  />

将自定义类从 input 移动到 select

input 上的自定义类移动到 select

input key 应用于另一个元素。

  <TablePagination
-  classes={{ input: 'foo' }}
+  classes={{ select: 'foo' }}
  />

Tabs

更新默认 indicatorColor 和 textColor prop 值

将默认 indicatorColortextColor prop 值更改为 "primary"。

这样做是为了匹配 Material Design 最常见的用例。

如果您希望保留 v4 颜色样式,请分别使用 "secondary""inherit",如下所示

-<Tabs />
+<Tabs indicatorColor="secondary" textColor="inherit" />

更新事件类型 (TypeScript)

onChange 中的 event 现在类型为 React.SyntheticEvent 而不是 React.ChangeEvent

-<Tabs onChange={(event: React.ChangeEvent<{}>, value: unknown) => {}} />
+<Tabs onChange={(event: React.SyntheticEvent, value: unknown) => {}} />

✅ 添加新的滚动按钮 props

控制滚动按钮的 API 已拆分为两个 props。

  • scrollButtons prop 控制滚动按钮何时显示,具体取决于可用空间。
  • allowScrollButtonsMobile prop 移除 CSS 媒体查询,该查询系统地隐藏移动设备上的滚动按钮。
-<Tabs scrollButtons="on" />
-<Tabs scrollButtons="desktop" />
-<Tabs scrollButtons="off" />
+<Tabs scrollButtons allowScrollButtonsMobile />
+<Tabs scrollButtons />
+<Tabs scrollButtons={false} />

Tab

更新默认 minWidth 和 maxWidth

默认最小和最大宽度已更改为匹配 Material Design 规范

  • minWidth 从 72px 更改为 90px。
  • maxWidth 从 264px 更改为 360px。

移除 span 和 wrapper

包裹 children 的 span 元素已被移除。wrapper classKey 也被移除。

你可以在这个 GitHub pull request 中找到关于此更改的更多详细信息。

  <button class="MuiTab-root">
-  <span class="MuiTab-wrapper">
      {icon}
      {label}
-  </span>
  </button>

TextField

✅ 更新默认 variant

将默认 variant 从 standard 更改为 outlined

standard 已从 Material Design 指南中移除。

-<TextField value="Standard" />
-<TextField value="Outlined" variant="outlined" />
+<TextField value="Standard" variant="standard" />
+<TextField value="Outlined" />

✅ 重命名 rowsMax

为了与 HTML 属性保持一致,将 rowsMax 属性重命名为 maxRows

-<TextField rowsMax={6}>
+<TextField maxRows={6}>

✅ 将 rows 替换为 minRows

为了实现动态调整大小,将 rows 属性重命名为 minRows

在以下情况下,你需要使用 minRows 属性

-<TextField rows={2} maxRows={5} />
+<TextField minRows={2} maxRows={5} />

使用 forward ref 代替 inputRef 属性

更改自定义 inputComponent 的 ref 转发预期。

组件应该转发 ref 属性而不是 inputRef 属性。

-function NumberFormatCustom(props) {
-  const { inputRef, onChange, ...other } = props;
+const NumberFormatCustom = React.forwardRef(function NumberFormatCustom(
+  props,
+  ref,
+) {
  const { onChange, ...other } = props;

  return (
    <NumberFormat
      {...other}
-     getInputRef={inputRef}
+     getInputRef={ref}

重命名 marginDense 和 inputMarginDense 类

marginDenseinputMarginDense 类重命名为 sizeSmallinputSizeSmall,以匹配 prop 属性。

-<Input margin="dense" />
+<Input size="small" />

更新 InputAdornment position 属性

将 InputAdornment 的 position 属性设置为 startend

如果用作 startAdornment 属性的值,则使用 start。如果用作 endAdornment 属性的值,则使用 end

-<TextField startAdornment={<InputAdornment>kg</InputAdornment>} />
-<TextField endAdornment={<InputAdornment>kg</InputAdornment>} />
+<TextField startAdornment={<InputAdornment position="start">kg</InputAdornment>} />
+<TextField endAdornment={<InputAdornment position="end">kg</InputAdornment>} />

TextareaAutosize

✅ 将 rows 替换为 minRows

移除 rows 属性,请改用 minRows 属性。

此更改旨在明确 prop 属性的行为。

-<TextareaAutosize rows={2} />
+<TextareaAutosize minRows={2} />

✅ 重命名 rowsMax

为了与 HTML 属性保持一致,将 rowsMax 属性重命名为 maxRows

-<TextareaAutosize rowsMax={6}>
+<TextareaAutosize maxRows={6}>

✅ 重命名 rowsMin

为了与 HTML 属性保持一致,将 rowsMin 属性重命名为 minRows

-<TextareaAutosize rowsMin={1}>
+<TextareaAutosize minRows={1}>

ToggleButton

✅ 更新导入

将组件从 lab 移动到 core。

该组件现在是稳定的。

-import ToggleButton from '@mui/lab/ToggleButton';
-import ToggleButtonGroup from '@mui/lab/ToggleButtonGroup';
+import ToggleButton from '@mui/material/ToggleButton';
+import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';

移除 span 和 label

包裹 children 的 span 元素已被移除。label classKey 也被移除。

你可以在这个 GitHub pull request 中找到关于此更改的更多详细信息。

  <button class="MuiToggleButton-root">
-  <span class="MuiToggleButton-label">
      {children}
-  </span>
  </button>

Tooltip

默认可交互

现在 Tooltip 默认是可交互的。

之前的默认行为不符合 WCAG 2.1 中的成功标准 1.4.3 ("可悬停")

为了反映新的默认值,该属性已重命名为 disableInteractive

如果你想恢复 v4 的行为,你可以应用以下差异

-<Tooltip>
+<Tooltip disableInteractive>

 # Interactive tooltips no longer need the `interactive` prop.
-<Tooltip interactive>
+<Tooltip>

Typography

移除 srOnly 变体

移除 srOnly 变体。

你可以将 visuallyHidden 实用程序与 sx 属性结合使用。

+import { visuallyHidden } from '@mui/utils';

-<Typography variant="srOnly">Create a user</Typography>
+<span style={visuallyHidden}>Create a user</span>

移除 color 和 style override 键

以下类和样式覆盖键已被移除

"colorInherit", "colorPrimary", "colorSecondary", "colorTextPrimary", "colorTextSecondary", "colorError", "displayInline" 和 "displayBlock"。

这些属性现在被认为是 MUISystem 的一部分,而不是 Typography 组件本身的一部分。

如果您仍然希望为它们添加覆盖,您可以使用 回调作为 styleOverrides 中的值

例如

 const theme = createTheme({
   components: {
     MuiTypography: {
-      styleOverrides: {
-        colorSecondary: {
-          marginTop: '20px',
-        },
-      },
+      styleOverrides: ({ ownerState }) => ({
+        ...ownerState.color === 'secondary' && {
+          marginTop: '20px',
+        },
+      }),
     },
   },
 });

Theme

默认背景颜色

现在,默认背景颜色在浅色模式下为 #fff,在深色模式下为 #121212

这与 Material Design 指南相符。

✅ 断点行为

现在,断点被视为值,而不是 范围

down(key) 的行为已更改为定义一个媒体查询,该查询低于相应断点(不包含)定义的值,而不是高于断点的范围。

between(start, end) 也已更新为定义实际开始值(包含)和结束值(不包含)之间的值的媒体查询。

当使用 down() 断点实用程序时,你需要将断点键向上更新一步。

当使用 between(start, end) 时,结束断点也应该向上更新一步。

以下是一些需要更改的示例

-theme.breakpoints.down('sm') // '@media (max-width:959.95px)' - [0, sm + 1) => [0, md)
+theme.breakpoints.down('md') // '@media (max-width:959.95px)' - [0, md)
-theme.breakpoints.between('sm', 'md') // '@media (min-width:600px) and (max-width:1279.95px)' - [sm, md + 1) => [0, lg)
+theme.breakpoints.between('sm', 'lg') // '@media (min-width:600px) and (max-width:1279.95px)' - [0, lg)
-theme.breakpoints.between('sm', 'xl') // '@media (min-width:600px)'
+theme.breakpoints.up('sm') // '@media (min-width:600px)'

当使用 Hidden 组件时,也应该这样做

-<Hidden smDown>{...}</Hidden> // '@media (min-width:600px)'
+<Hidden mdDown>{...}</Hidden> // '@media (min-width:600px)'

断点尺寸

默认断点已更改,以更好地匹配常见的用例以及 Material Design 指南。

你可以在这个 GitHub issue 中找到关于此更改的更多详细信息

 {
   xs: 0,
   sm: 600,
-  md: 960,
+  md: 900,
-  lg: 1280,
+  lg: 1200,
-  xl: 1920,
+  xl: 1536,
 }

如果你更喜欢旧的断点值,请使用以下代码片段

import { createTheme } from '@mui/material/styles';

const theme = createTheme({
  breakpoints: {
    values: {
      xs: 0,
      sm: 600,
      md: 960,
      lg: 1280,
      xl: 1920,
    },
  },
});

✅ 替换 theme.breakpoints.width

theme.breakpoints.width 实用程序已被移除,因为它显得多余。

使用 theme.breakpoints.values 可以获得相同的值。

-theme.breakpoints.width('md')
+theme.breakpoints.values.md

更新 theme.palette.augmentColor helper

theme.palette.augmentColor helper 的签名已更改

-theme.palette.augmentColor(red);
+theme.palette.augmentColor({ color: red, name: 'brand' });

移除 theme.typography.round helper

theme.typography.round helper 已被移除,因为它不再使用。

如果你需要它,请使用以下函数

function round(value) {
  return Math.round(value * 1e5) / 1e5;
}

@mui/types

重命名导出的 Omit 类型

该模块现在称为 DistributiveOmit

此更改消除了与 TypeScript v3.5 中引入的内置 Omit helper 的混淆。

内置的 Omit 虽然类似,但它是非分布式的。当应用于联合类型时,这会导致差异。有关更多详细信息,请参见此 Stack Overflow 答案

-import { Omit } from '@mui/types';
+import { DistributiveOmit } from '@mui/types';