跳至內容
+

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

✅ 更新 import

將組件從 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

✅ 更新 import

將組件從 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 開發者工具 "模擬焦點",或 React 開發者工具 prop 設定器。

更新 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 import

將 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"

checkbox color prop 現在預設為 "primary"。要繼續使用 "secondary" 顏色,您必須明確指示 secondary。這使 checkbox 更接近 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

用 border-color 替換 background-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

新增必要的 label prop

label prop 現在是必需的。如果您正在使用沒有 labelFormControlLabel,您可以將其替換為僅包含 control prop 的值。

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

Grid

✅ 重新命名 justify prop

為了與 CSS 屬性名稱對齊,將 justify prop 重新命名為 justifyContent

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

✅ 移除 align 和 justify props 和 classes

props alignItemsalignContentjustifyContent——以及它們的 classes 和樣式覆蓋 keys——已被移除

"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 組件本身。

如果您仍然希望為它們添加覆蓋,您可以使用 callback 作為 styleOverrides 中的值

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

變更負邊距

負邊距僅適用於 grid container 的頂部和左側。如果您需要所有側面的負邊距,我們建議改為使用新的 Grid v2

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

要了解更多關於 Grid2 的資訊,請查看 Grid2 組件文件升級指南

GridList

✅ 重新命名 GridList 組件

為了與目前的 Material Design 命名對齊,將 GridList 組件重新命名為 ImageList

重新命名 GridList props

  • 為了與 CSS 屬性對齊,將 GridList spacing prop 重新命名為 gap
  • 將 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"

此變更的目的是為了在 Material Design 停止記錄 icon button 模式時,更好地匹配 Google 的產品。

- <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。

根據您的使用案例,您可以對子元素使用 callback 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

✅ 更新 import

將組件從 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。

根據您的使用案例,您可以對子元素使用 callback ref,或在子組件中使用 effect hook。

Radio

更新預設 color prop

radio color prop 現在預設為 "primary"。

要繼續使用 "secondary" 顏色,您必須明確指示 secondary

這使 radio 更接近 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

✅ 更新 imports

將組件從 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 指南中移除。

如果您正在使用 form control 組件組合 Select,您只需要更新 FormControl——select 從其 context 繼承 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

✅ 更新 import

將組件從 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 來降低 slider 的密度,使其更接近 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

✅ 更新 import

將組件從 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 不再具有陰影,也不再繼承來自 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

為了 API 的一致性,將 onChangeRowsPerPage 重新命名為 onRowsPerPageChange,並將 onChangePage 重新命名為 onPageChange

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

分離標籤 class

用於不同表格分頁標籤的分離 class。

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

將自訂 class 從 input 移動到 select

input 上的自訂 class 移動到 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) => {}} />

✅ 新增 scroll button props

控制 scroll button 的 API 已拆分為兩個 props。

  • scrollButtons prop 控制 scroll button 何時顯示,取決於可用空間。
  • allowScrollButtonsMobile prop 移除了系統性地在行動裝置上隱藏 scroll button 的 CSS media query。
-<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

包裝子元素的 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 prop 重新命名為 maxRows

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

✅ 將 rows 替換為 minRows

為了動態調整大小,將 rows prop 重新命名為 minRows

在以下情況下,您需要使用 minRows prop

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

Forward ref 而不是 inputRef prop

變更自訂 inputComponent 上的 ref forwarding 預期。

組件應 forwarding ref prop 而不是 inputRef prop。

-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 class

為了與 prop 匹配,將 marginDenseinputMarginDense class 重新命名為 sizeSmallinputSizeSmall

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

更新 InputAdornment position prop

將 InputAdornment position prop 設定為 startend

如果用作 startAdornment prop 的值,請使用 start。如果用作 endAdornment prop 的值,請使用 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 prop,改用 minRows prop。

此變更旨在闡明 prop 的行為。

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

✅ 重新命名 rowsMax

為了與 HTML 屬性保持一致性,將 rowsMax prop 重新命名為 maxRows

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

✅ 重新命名 rowsMin

為了與 HTML 屬性保持一致性,將 rowsMin prop 重新命名為 minRows

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

ToggleButton

✅ 更新 import

將組件從 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 ("hoverable")

為了反映新的預設值,該 prop 已重新命名為 disableInteractive

如果您想還原 v4 行為,可以套用以下 diff

-<Tooltip>
+<Tooltip disableInteractive>

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

Typography

移除 srOnly variant

移除 srOnly variant。

您可以將 visuallyHidden utility 與 sx prop 結合使用。

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

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

移除 color 和 style override key

以下 class 和 style override key 已被移除

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

這些 props 現在被視為 MUISystem 而不是 Typography 組件本身的一部分。

如果您仍然希望為它們添加覆蓋,您可以使用 callback 作為 styleOverrides 中的值

例如

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

Theme

預設背景顏色

預設背景顏色在淺色模式下現在為 #fff,在深色模式下為 #121212

這符合 Material Design 指南。

✅ Breakpoint 行為

Breakpoint 現在被視為值,而不是 ranges

down(key) 的行為已變更為定義一個媒體查詢,該查詢低於對應 breakpoint (exclusive) 定義的值,而不是高於該 breakpoint。

between(start, end) 也已更新為定義一個媒體查詢,用於實際開始 (inclusive) 和結束 (exclusive) 值之間的值。

當使用 down() breakpoint utility 時,您需要將 breakpoint key 向上更新一步。

當使用 between(start, end) 時,結束 breakpoint 也應向上更新一步。

以下是一些所需變更的範例

-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)'

Breakpoint 尺寸

預設 breakpoint 已變更為更符合常見使用案例以及 Material Design 指南。

您可以在 此 GitHub issue 中找到有關此變更的更多詳細資訊

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

如果您偏好舊的 breakpoint 值,請使用以下程式碼片段

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 utility 已被移除,因為它是多餘的。

使用 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 type

該模組現在稱為 DistributiveOmit

此變更消除了與 TypeScript v3.5 中引入的內建 Omit helper 之間的混淆。

內建的 Omit 雖然相似,但卻是非分配式的。這會在應用於 union type 時導致差異。請參閱此 Stack Overflow 回答以取得更多詳細資訊

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