MUI5 + React 使用makeStyles时无法访问默认主题报错:Cannot read properties of undefined (reading 'primary')
你遇到的Cannot read properties of undefined (reading 'primary')报错,核心原因是MUI5中的@mui/styles包是独立于核心组件库的,它不会自动获取MUI的默认主题。下面是具体的解决步骤和修正后的代码:
问题根源
在MUI5里,@mui/styles(也就是原Material-UI v4的makeStyles)不再和组件库的主题系统自动关联,如果你没有手动提供主题上下文,makeStyles回调里的theme参数就会是undefined,自然无法访问theme.palette.primary.light这类属性。
解决方案
1. 引入ThemeProvider和默认主题
从@mui/material/styles导入ThemeProvider和createTheme,创建一个MUI默认主题的实例,然后用它包裹你的整个App组件,这样makeStyles就能从上下文中拿到主题了。
2. 修正makeStyles的语法错误
你的代码里root的写法({ ... })是用来接收组件props的语法,但这里你并没有传递props,直接写成{ ... }即可;另外theme.color是不存在的主题属性,建议改成theme.palette.common.white这类合法值,或者用theme.palette.getContrastText()来自动生成适配底色的文本颜色。
修正后的完整代码
import { Grid, Card, CardContent, Typography, CardActions, Button, AppBar, Toolbar, Box, IconButton, Menu, MenuItem, InputBase, alpha, styled, Badge, Container, CardHeader, CardMedia } from '@mui/material'; import EmailIcon from '@mui/icons-material/Email'; import NotificationsIcon from '@mui/icons-material/Notifications'; import React, { Fragment } from 'react'; import { makeStyles } from '@mui/styles'; // 引入ThemeProvider和默认主题生成工具 import { ThemeProvider, createTheme } from '@mui/material/styles'; // 创建MUI默认主题实例 const theme = createTheme(); const useStyles = makeStyles((theme) => ({ root: { backgroundColor: theme.palette.primary.light, // 使用主题中合法的文本颜色,适配浅底色 color: theme.palette.common.white, padding: theme.spacing(2) // 用theme.spacing统一控制间距 }, })); const App = () => { const classes = useStyles(); return( // 用ThemeProvider包裹整个应用,传递主题上下文 <ThemeProvider theme={theme}> <Fragment> <Container className={classes.root}> <Typography> this is a very random text to fill </Typography> </Container> </Fragment> </ThemeProvider> ) } export default App;
额外提示
如果是新的MUI5项目,官方更推荐使用sx prop或者styled API来替代makeStyles,因为它们能更好地和MUI5的主题系统集成,不需要额外配置ThemeProvider(只要你使用了MUI的组件,主题上下文就已经存在)。比如用sx prop的简化写法:
<Container sx={{ backgroundColor: theme => theme.palette.primary.light, color: theme => theme.palette.common.white, padding: 2 }}> <Typography> this is a very random text to fill </Typography> </Container>
内容的提问来源于stack exchange,提问作者majd shaheen

