React+Material UI使用styled组件时出现TypeError:无法读取'up'属性
问题解决:TypeError: Cannot read properties of undefined (reading 'up')
错误原因
该错误是由于以下两个核心问题导致的:
- 使用了纯
@emotion/styled而非 Material UI 集成的 styled 工具,导致无法自动获取 MUI 主题对象 - 悬停状态的选择器语法错误(使用了转义的 HTML 实体而非正确的 Emotion 语法)
修复步骤
1. 替换 styled 导入
将纯 Emotion styled 替换为 MUI 提供的 styled 工具,它会自动注入 MUI 主题:
// 替换原导入 import styled from '@mui/material/styles/styled';
2. 修正悬停选择器语法
将转义的 "&:hover" 改为 Emotion 支持的 '&:hover':
3. 确保应用包裹在 ThemeProvider 中
在根组件(如 App.js)中使用 MUI 的 ThemeProvider 提供主题上下文:
import { ThemeProvider, createTheme } from '@mui/material/styles'; const theme = createTheme(); function App() { return ( <ThemeProvider theme={theme}> <Hero /> </ThemeProvider> ); }
4. 优化组件定义(可选但推荐)
将 styled 组件移到函数组件外部,避免每次渲染都重新创建组件:
完整修正代码
import styled from '@mui/material/styles/styled'; import { Grid, Typography } from '@mui/material'; import { Box, Container } from '@mui/system'; import React from 'react'; import burger from '../../static/burger1.jpg'; import meat from '../../static/meat.jpg'; import appetizer from '../../static/appetizer.jpg'; import drinks from '../../static/drinks.jpg'; const StyledCard = styled(Box)(({ theme }) => ({ display: 'flex', justifyContent: 'center', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', backgroundSize: 'cover', cursor: 'pointer', [theme.breakpoints.up('md')]: { height: 400, }, [theme.breakpoints.down('md')]: { height: 200, }, '&:hover': { opacity: 0.8, boxSizing: 'border-box', zIndex: 1, transition: `all 0.45s ease`, }, })); const StyledTypography = styled(Typography)({ textAlign: 'center', color: 'white', backgroundColor: 'tomato', fontSize: 20, }); const Styledwrapper = styled(Box)(({ theme }) => ({ [theme.breakpoints.up('md')]: { paddingTop: '140%', }, [theme.breakpoints.down('md')]: { paddingTop: '40%', }, width: '80%', })); const Hero = () => { return ( <Container> <Grid container direction={'row'} columnSpacing={2} rowSpacing={2}> <Grid item md={3} xs={6}> <StyledCard sx={{ backgroundImage: `url(${meat})` }}> <Styledwrapper> <StyledTypography>Meat</StyledTypography> </Styledwrapper> </StyledCard> </Grid> <Grid item md={3} xs={6}> <StyledCard sx={{ backgroundImage: `url(${burger})` }}> <Styledwrapper> <StyledTypography>Burger</StyledTypography> </Styledwrapper> </StyledCard> </Grid> <Grid item md={3} xs={6}> <StyledCard sx={{ backgroundImage: `url(${appetizer})` }}> <Styledwrapper> <StyledTypography>Appetizer</StyledTypography> </Styledwrapper> </StyledCard> </Grid> <Grid item md={3} xs={6}> <StyledCard sx={{ backgroundImage: `url(${drinks})` }}> <Styledwrapper> <StyledTypography>Drinks</StyledTypography> </Styledwrapper> </StyledCard> </Grid> </Grid> </Container> ); }; export default Hero;
内容的提问来源于stack exchange,提问作者Abhishek kumar
相关产品推荐
相关产品推荐

