MUI组件报错TypeError: Cannot read properties of undefined (reading '800')
解决React+Next.js中MUI组件报错:TypeError: Cannot read properties of undefined (reading '800')
错误原因
核心问题是直接将ThemeOptions类型的配置对象传给了ThemeProvider,而MUI的ThemeProvider需要的是经过createTheme函数处理后的完整主题实例。未处理的配置对象缺少MUI内部依赖的完整结构,导致组件在访问主题中的palette.grey.800时找不到对应属性,触发undefined读取错误。
修复步骤
- 修改主题文件,用
createTheme生成完整主题
在主题定义文件中导入createTheme,用它处理原始配置对象,导出处理后的完整主题实例。 - 修正组件中
ThemeProvider的传入值
确保传给ThemeProvider的是处理后的主题,而非原始配置。 - 补充Menu组件的必要属性(可选但重要)
当前Menu组件缺少anchorEl属性,会导致菜单无法正确定位,建议一起修复。
修改后的代码示例
主题文件(@/styles/themes/mainTheme.js)
import NextLink from 'next/link'; import { ThemeOptions, createTheme } from '@mui/material/styles'; // 导入createTheme import { forwardRef } from 'react'; const LinkBehaviour = forwardRef(function LinkBehaviour(props, ref) { //@ts-ignore return <NextLink ref={ref} {...props} />; }); // main color const primaryColor = '#116466'; const lightPrimaryColor = '#2B7E80'; const darkPrimaryColor = '#004B4D'; // secondary color const secondaryColor = '#FFB57C'; const lightSecondaryColor = '#FFFFFF'; const darkSecondaryColor = '#000000'; // custom colors export const customColors = { black: '#000000', white: '#FFFFFF', error: '#F84F31', success: '#23C552', text: '#D1E8E2', darkBackground: '#2C3531', lightBackground: '#E4E4E4' } export const breakpoints = { xLarge: '1500px', Large: '1280px', Medium: '960px', Small: '640px', Tiny: '480px' } export const generalVariables = { contentPadding: '0px 140px' } const mainThemeOptions: ThemeOptions = { // 重命名为配置项变量 palette: { grey: { 800: '#555555', }, primary: { main: primaryColor, light: lightPrimaryColor, dark: darkPrimaryColor }, secondary: { main: secondaryColor, light: lightSecondaryColor, dark: darkSecondaryColor }, }, }; // 用createTheme处理配置,导出完整主题实例 const MainTheme = createTheme(mainThemeOptions); export default MainTheme;
HeaderProfileButton组件
import React, { useState, useRef } from 'react'; import { Menu, MenuItem, Avatar, Box, ThemeProvider} from '@mui/material'; import MainTheme, { customColors } from '@/styles/themes/mainTheme'; import Link from 'next/link'; import Button from '@mui/material/Button'; import AccountCircleIcon from '@mui/icons-material/AccountCircle'; export const HeaderProfileButton = () => { const [isOpened, setIsOpened] = useState(false); // 初始设为false,避免页面加载就显示菜单 const anchorRef = useRef(null); // 新增ref作为Menu的锚点 const handleClick = () => { setIsOpened(prev => !prev); }; const handleClose = () => { setIsOpened(false); }; return ( <ThemeProvider theme={MainTheme}> <Button ref={anchorRef} onClick={handleClick} sx={{display: 'flex'}} > <AccountCircleIcon sx={{height: '60px', width: '60px', color: customColors.text}} /> </Button> <Menu anchorEl={anchorRef.current} // 设置锚点元素 open={isOpened} onClose={handleClose} // 点击外部关闭菜单 anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} // 定位方式 transformOrigin={{ vertical: 'top', horizontal: 'right' }} sx={{ backgroundColor: customColors.darkBackground, '& .MuiMenuItem-root': { color: customColors.text } // 设置菜单项文字颜色 }} > <MenuItem onClick={handleClose}>个人中心</MenuItem> <MenuItem onClick={handleClose}>退出登录</MenuItem> </Menu> </ThemeProvider> ); };
额外说明
- 之前的缓存清理操作无法解决问题,因为错误根源是主题配置的使用方式错误。
- 如果全局已经配置了
ThemeProvider,建议组件中不要再嵌套,避免主题冲突。
内容的提问来源于stack exchange,提问作者T T
相关产品推荐
相关产品推荐

