Troubleshooting
This document covers known issues and common problems encountered when migrating from Material UI v4 to v5.
Material UI v5 migration
- Getting started
- Breaking changes part one: style and theme
- Breaking changes part two: components
- Migrating from JSS
- Troubleshooting 👈 you are here
Styles broken after migrating to v5
There are two reasons why component styles may be broken after you've completed all steps in the migration process.
First, check if you have configured the StyledEngineProvider
correctly, as shown in the Style library section.
If the StyledEngineProvider
is already used at the top of your application and the styles are still broken, it may be the case that you still have @material-ui/core
in your application.
This could be caused by other dependencies in the app that still rely on Material UI v4.
To check this, run npm ls @material-ui/core
(or yarn why @material-ui/core
).
If your project contains such dependencies, you will see a list that looks something like this:
$ npm ls @material-ui/core
project@0.1.0 /path/to/project
└─┬ @mui/x-data-grid@4.0.0
└── @material-ui/core@4.12.3
The output above indicates that @material-ui/core
is a dependency of @mui/x-data-grid
.
In this specific example, you would need to bump the version of @mui/x-data-grid
to v5 so that it depends on @mui/material
instead.
Storybook and Emotion
If your project uses Storybook v6.x, you will need to update the .storybook/main.js
Webpack config to use the most recent version of Emotion:
// .storybook/main.js
const path = require('path');
const toPath = (filePath) => path.join(process.cwd(), filePath);
module.exports = {
webpackFinal: async (config) => {
return {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
'@emotion/core': toPath('node_modules/@emotion/react'),
'emotion-theming': toPath('node_modules/@emotion/react'),
},
},
};
},
};
Next, update .storybook/preview.js
to prevent Storybook's Docs tab from displaying an empty page:
// .storybook/preview.js
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { ThemeProvider as Emotion10ThemeProvider } from 'emotion-theming';
const defaultTheme = createTheme(); // or your custom theme
const withThemeProvider = (Story, context) => {
return (
<Emotion10ThemeProvider theme={defaultTheme}>
<ThemeProvider theme={defaultTheme}>
<Story {...context} />
</ThemeProvider>
</Emotion10ThemeProvider>
);
};
export const decorators = [withThemeProvider];
// ...other storybook exports
Cannot read property scrollTop of null
This error comes from Fade
, Grow
, Slide
, Zoom
components due to a missing DOM node.
Make sure that the children forward the ref
to the DOM for custom components:
// Ex. 1-1 ❌ This will cause an error because the Fragment is not a DOM node:
<Fade in>
<React.Fragment>
<CustomComponent />
</React.Fragment>
</Fade>
// Ex. 1-2 ✅ Add a DOM node such as this div:
<Fade in>
<div>
<CustomComponent />
</div>
</Fade>
// Ex. 2-1 ❌ This will cause an error because `CustomComponent` does not forward `ref` to the DOM:
function CustomComponent() {
return <div>...</div>;
}
<Fade in>
<CustomComponent />
</Fade>;
// Ex. 2-2 ✅ Add `React.forwardRef` to forward `ref` to the DOM:
const CustomComponent = React.forwardRef(function CustomComponent(props, ref) {
return (
<div ref={ref}>
...
</div>
)
})
<Fade in>
<CustomComponent />
</Fade>
For more details, checkout this issue on GitHub.
[Types] Property "palette", "spacing" does not exist on type 'DefaultTheme'
This error arises because makeStyles
is now exported from the @mui/styles
package, which does not know about Theme
in the core package.
To fix this, you need to augment the DefaultTheme
(empty object) in @mui/styles
with Theme
from the core.
Read more about module augmentation in the official TypeScript docs.
TypeScript
Add this snippet to your theme file:
// it could be your App.tsx file or theme file that is included in your tsconfig.json
import { Theme } from '@mui/material/styles';
declare module '@mui/styles/defaultTheme' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface (remove this line if you don't have the rule enabled)
interface DefaultTheme extends Theme {}
}
JavaScript
If you are using an IDE like VSCode which is able to infer types from a d.ts
file, create index.d.ts
in your src
folder and add the following lines of code:
// index.d.ts
declare module '@mui/private-theming' {
import type { Theme } from '@mui/material/styles';
interface DefaultTheme extends Theme {}
}
[Jest] SyntaxError: Unexpected token 'export'
@mui/material/colors/red
is considered private since v1.0.0.
To fix this error, you must replace the import.
For more details, see this GitHub issue.
We recommend using this codemod to fix all imports in your project:
npx @mui/codemod@latest v5.0.0/optimal-imports <path>
You can fix it manually like this:
-import red from '@mui/material/colors/red';
+import { red } from '@mui/material/colors';
makeStyles - TypeError: Cannot read property 'drawer' of undefined
This error occurs when calling useStyles
or withStyles
outside of the scope of <ThemeProvider>
, as in the following example:
import * as React from 'react';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import makeStyles from '@mui/styles/makeStyles';
import Card from '@mui/material/Card';
import CssBaseline from '@mui/material/CssBaseline';
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
backgroundColor: theme.palette.primary.main,
color: theme.palette.common.white,
},
}));
const theme = createTheme();
function App() {
const classes = useStyles(); // ❌ called outside of ThemeProvider
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Card className={classes.root}>...</Card>
</ThemeProvider>
);
}
export default App;
You can fix this by moving useStyles
inside another component so that it is called under <ThemeProvider>
:
// ...imports
function AppContent(props) {
const classes = useStyles(); // ✅ This is safe because it is called inside ThemeProvider
return <Card className={classes.root}>...</Card>;
}
function App(props) {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<AppContent {...props} />
</ThemeProvider>
);
}
export default App;
TypeError: Cannot read properties of undefined (reading 'pxToRem')
This error results from trying to access an empty theme.
Make sure that you have addressed the following issues:
styled
should only be imported from@mui/material/styles
(if you are not using the standalone@mui/system
):
import { styled } from '@mui/material/styles';
useStyles
cannot be called outside of<ThemeProvider>
. To fix this problem, follow the instructions in this section.
For more details, see this GitHub issue.
Still having problems?
If you're encountering a problem not covered here, please create a GitHub issue with this title format: [Migration] Summary of your issue.