React集成Material UI与Joy UI出现空白页及类型错误
问题:同时使用Material UI与Joy UI导致页面空白,控制台抛出TypeError
编译成功可访问http://localhost:3000,但页面完全空白,Chrome控制台报错:
Uncaught TypeError: Cannot read properties of undefined (reading '1')
相关代码:
import React from 'react'; import { CssVarsProvider } from '@mui/joy/styles'; import {Box, Card, CardContent, Container, Grid} from "@mui/material"; import write from "../../assets/images/svg/writing.svg"; import {Button, FormControl, FormLabel, Input, Typography} from "@mui/joy"; const GuardianDetails = () => { return ( <> <CssVarsProvider> <Container maxWidth="sm"> <Card> <CardContent> <Grid container spacing={2} justifyContent="center" alignItems="center"> <Grid item xs={8}> <Box> <div> <img src={write} alt="write" width={300} height={300} /> </div> </Box> </Grid> <Grid item xs={4}> <Box> <div> <Typography level="h4" component="h1"> <b>Welcome!</b> </Typography> <Typography level="body2">Sign in to continue.</Typography> </div> <FormControl> <FormLabel>Email</FormLabel> <Input // html input attribute name="email" type="email" placeholder="johndoe@email.com" /> </FormControl> <FormControl> <FormLabel>Password</FormLabel> <Input // html input attribute name="password" type="password" placeholder="password" /> </FormControl> <Button sx={{ mt: 1 /* margin top */ }}>Log in</Button> </Box> </Grid> </Grid> </CardContent> </Card> </Container> </CssVarsProvider> </> ); }; export default GuardianDetails;
问题原因
错误源于Material UI(MUI)组件直接嵌套在Joy UI的CssVarsProvider内部。CssVarsProvider是Joy UI专属的样式上下文提供器,会修改全局CSS变量,导致MUI组件的样式解析逻辑异常,进而抛出类型错误。
解决方案
方案1:分离样式上下文,分别包裹组件树
将MUI组件和Joy UI组件拆分,用各自的样式提供器包裹,避免上下文冲突。MUI需使用ThemeProvider(来自@mui/material/styles),Joy UI保留CssVarsProvider。
修改后代码示例:
import React from 'react'; import { CssVarsProvider } from '@mui/joy/styles'; import { ThemeProvider, createTheme } from '@mui/material/styles'; import {Box, Card, CardContent, Container, Grid} from "@mui/material"; import write from "../../assets/images/svg/writing.svg"; import {Button, FormControl, FormLabel, Input, Typography} from "@mui/joy"; // 创建MUI主题实例 const muiTheme = createTheme(); const GuardianDetails = () => { return ( <> {/* MUI组件用ThemeProvider包裹 */} <ThemeProvider theme={muiTheme}> <Container maxWidth="sm"> <Card> <CardContent> <Grid container spacing={2} justifyContent="center" alignItems="center"> <Grid item xs={8}> <Box> <div> <img src={write} alt="write" width={300} height={300} /> </div> </Box> </Grid> <Grid item xs={4}> {/* Joy UI组件用CssVarsProvider单独包裹 */} <CssVarsProvider> <Box> <div> <Typography level="h4" component="h1"> <b>Welcome!</b> </Typography> <Typography level="body2">Sign in to continue.</Typography> </div> <FormControl> <FormLabel>Email</FormLabel> <Input name="email" type="email" placeholder="johndoe@email.com" /> </FormControl> <FormControl> <FormLabel>Password</FormLabel> <Input name="password" type="password" placeholder="password" /> </FormControl> <Button sx={{ mt: 1 }}>Log in</Button> </Box> </CssVarsProvider> </Grid> </Grid> </CardContent> </Card> </Container> </ThemeProvider> </> ); }; export default GuardianDetails;
方案2:统一使用单个UI库
若项目无强制需求同时使用两个库,建议只保留其中一个(MUI或Joy UI),彻底规避样式上下文冲突。例如将所有Joy UI组件替换为MUI对应组件,或反之。
内容的提问来源于stack exchange,提问作者Kelvin Kahihu
相关产品推荐
相关产品推荐

