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:
$ <span class="token function">npm</span> <span class="token function">ls</span> @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:
<span class="token comment">// .storybook/main.js</span>
<span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'path'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token function-variable function">toPath</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">filePath</span><span class="token punctuation">)</span> <span class="token operator">=></span> path<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>process<span class="token punctuation">.</span><span class="token function">cwd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> filePath<span class="token punctuation">)</span><span class="token punctuation">;</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token function-variable function">webpackFinal</span><span class="token operator">:</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>
<span class="token operator">...</span>config<span class="token punctuation">,</span>
<span class="token literal-property property">resolve</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token operator">...</span>config<span class="token punctuation">.</span>resolve<span class="token punctuation">,</span>
<span class="token literal-property property">alias</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token operator">...</span>config<span class="token punctuation">.</span>resolve<span class="token punctuation">.</span>alias<span class="token punctuation">,</span>
<span class="token string-property property">'@emotion/core'</span><span class="token operator">:</span> <span class="token function">toPath</span><span class="token punctuation">(</span><span class="token string">'node_modules/@emotion/react'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token string-property property">'emotion-theming'</span><span class="token operator">:</span> <span class="token function">toPath</span><span class="token punctuation">(</span><span class="token string">'node_modules/@emotion/react'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
Next, update .storybook/preview.js
to prevent Storybook's Docs tab from displaying an empty page:
<span class="token comment">// .storybook/preview.js</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> ThemeProvider<span class="token punctuation">,</span> createTheme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/styles'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> ThemeProvider <span class="token keyword">as</span> Emotion10ThemeProvider <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'emotion-theming'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> defaultTheme <span class="token operator">=</span> <span class="token function">createTheme</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// or your custom theme</span>
<span class="token keyword">const</span> <span class="token function-variable function">withThemeProvider</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">Story<span class="token punctuation">,</span> context</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Emotion10ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>defaultTheme<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>defaultTheme<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Story</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token operator">...</span>context<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">ThemeProvider</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Emotion10ThemeProvider</span></span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> decorators <span class="token operator">=</span> <span class="token punctuation">[</span>withThemeProvider<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">// ...other storybook exports</span>
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:
<span class="token comment">// Ex. 1-1 ❌ This will cause an error because the Fragment is not a DOM node:</span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Fade</span></span> <span class="token attr-name">in</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">React.Fragment</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">CustomComponent</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">React.Fragment</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Fade</span></span><span class="token punctuation">></span></span>
<span class="token comment">// Ex. 1-2 ✅ Add a DOM node such as this div:</span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Fade</span></span> <span class="token attr-name">in</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">CustomComponent</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Fade</span></span><span class="token punctuation">></span></span>
<span class="token comment">// Ex. 2-1 ❌ This will cause an error because `CustomComponent` does not forward `ref` to the DOM:</span>
<span class="token keyword">function</span> <span class="token function">CustomComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token operator">...</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Fade</span></span> <span class="token attr-name">in</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">CustomComponent</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Fade</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token comment">// Ex. 2-2 ✅ Add `React.forwardRef` to forward `ref` to the DOM:</span>
<span class="token keyword">const</span> CustomComponent <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">forwardRef</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">CustomComponent</span><span class="token punctuation">(</span><span class="token parameter">props<span class="token punctuation">,</span> ref</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>ref<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
<span class="token operator">...</span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Fade</span></span> <span class="token attr-name">in</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">CustomComponent</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Fade</span></span><span class="token punctuation">></span></span>
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:
<span class="token comment">// it could be your App.tsx file or theme file that is included in your tsconfig.json</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> Theme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/styles'</span><span class="token punctuation">;</span>
declare module <span class="token string">'@mui/styles/defaultTheme'</span> <span class="token punctuation">{</span>
<span class="token comment">// eslint-disable-next-line @typescript-eslint/no-empty-interface (remove this line if you don't have the rule enabled)</span>
<span class="token keyword">interface</span> <span class="token class-name">DefaultTheme</span> <span class="token keyword">extends</span> <span class="token class-name">Theme</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
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:
<span class="token comment">// index.d.ts</span>
declare module <span class="token string">'@mui/private-theming'</span> <span class="token punctuation">{</span>
<span class="token keyword">import</span> type <span class="token punctuation">{</span> Theme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/styles'</span><span class="token punctuation">;</span>
<span class="token keyword">interface</span> <span class="token class-name">DefaultTheme</span> <span class="token keyword">extends</span> <span class="token class-name">Theme</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
[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 v5.0.0/optimal-imports <span class="token operator"><</span>path<span class="token operator">></span>
You can fix it manually like this:
<span class="token deleted-sign deleted"><span class="token prefix deleted">-</span><span class="token line">import red from '@mui/material/colors/red';
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">import { red } from '@mui/material/colors';</span></span>
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:
<span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> ThemeProvider<span class="token punctuation">,</span> createTheme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/styles'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> makeStyles <span class="token keyword">from</span> <span class="token string">'@mui/styles/makeStyles'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> Card <span class="token keyword">from</span> <span class="token string">'@mui/material/Card'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> CssBaseline <span class="token keyword">from</span> <span class="token string">'@mui/material/CssBaseline'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> useStyles <span class="token operator">=</span> <span class="token function">makeStyles</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">theme</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
<span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token literal-property property">display</span><span class="token operator">:</span> <span class="token string">'flex'</span><span class="token punctuation">,</span>
<span class="token literal-property property">backgroundColor</span><span class="token operator">:</span> theme<span class="token punctuation">.</span>palette<span class="token punctuation">.</span>primary<span class="token punctuation">.</span>main<span class="token punctuation">,</span>
<span class="token literal-property property">color</span><span class="token operator">:</span> theme<span class="token punctuation">.</span>palette<span class="token punctuation">.</span>common<span class="token punctuation">.</span>white<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> theme <span class="token operator">=</span> <span class="token function">createTheme</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> classes <span class="token operator">=</span> <span class="token function">useStyles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ❌ called outside of ThemeProvider</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>theme<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">CssBaseline</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Card</span></span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">.</span>root<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token operator">...</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Card</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">ThemeProvider</span></span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App<span class="token punctuation">;</span>
You can fix this by moving useStyles
inside another component so that it is called under <ThemeProvider>
:
<span class="token comment">// ...imports</span>
<span class="token keyword">function</span> <span class="token function">AppContent</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> classes <span class="token operator">=</span> <span class="token function">useStyles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ✅ This is safe because it is called inside ThemeProvider</span>
<span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Card</span></span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">.</span>root<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token operator">...</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Card</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>theme<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">CssBaseline</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AppContent</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token operator">...</span>props<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">ThemeProvider</span></span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App<span class="token punctuation">;</span>
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
):
<span class="token keyword">import</span> <span class="token punctuation">{</span> styled <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/styles'</span><span class="token punctuation">;</span>
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.