You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React18下用@emotion/styled替代makeStyles样式无效求助

问题:React 18 替换 makeStyles 为 @emotion/styled 后样式未达预期

React 18 移除了 makeStyles,我尝试用 @emotion/styled 配置样式,但页面样式和预期不符。

预期样式

预期样式

实际样式

实际样式

当前 App.js 代码

import React from 'react';
import { Typography, AppBar } from '@mui/material';
import styled from '@emotion/styled';
import VideoPlayer from './components/VideoPlayer';
import Options from './components/Options';
import Notification from './components/Notification';


// * Style dosyası bağlandı
const useStyles = styled(theme => ({
  appBar: {
    borderRadius: 15,
    margin: '30px 100px',
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    width: '600px',
    border: '2px solid black',

    [theme.breakpoints.down('xs')]: {
      width: '90%',
    },
  },
  image: {
    marginLeft: '15px',
  },
  wrapper: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    width: '100%',
  },
}));

const App = () => {
  // * Style dosyası çağırıldı
  //* className olarak elementlere tanımlandı
  const classes=useStyles();

  return (
    <div className={classes.wrapper}>
      <AppBar className={classes.appBar} position='static' color='inherit'>
        <Typography variant='h2' align='center'>
          Video Conferencing App
        </Typography>
      </AppBar>
      <VideoPlayer />
      <Options>
        <Notification />
      </Options>
    </div>
  )
}

export default App

错误原因

你混淆了 @emotion/styled 和 makeStyles 的用法:styled 是用来创建带样式的自定义组件,而非生成类名字典。原代码用 styled 模拟 makeStyles 的写法,无法正确生成有效样式类名,导致样式不生效。


解决方案

提供三种可行方案,按需选择:

方案1:使用 MUI 官方 styled 组件模式

直接基于 MUI 组件创建带样式的自定义组件,符合 MUI 推荐的用法:

import React from 'react';
import { Typography, AppBar } from '@mui/material';
import { styled } from '@mui/material/styles';
import VideoPlayer from './components/VideoPlayer';
import Options from './components/Options';
import Notification from './components/Notification';

// 自定义带样式的外层容器
const Wrapper = styled('div')(({ theme }) => ({
  display: 'flex',
  flexDirection: 'column',
  alignItems: 'center',
  width: '100%',
}));

// 自定义带样式的AppBar
const StyledAppBar = styled(AppBar)(({ theme }) => ({
  borderRadius: 15,
  margin: '30px 100px',
  display: 'flex',
  flexDirection: 'row',
  justifyContent: 'center',
  alignItems: 'center',
  width: '600px',
  border: '2px solid black',
  // 响应式断点
  [theme.breakpoints.down('xs')]: {
    width: '90%',
  },
}));

const App = () => {
  return (
    <Wrapper>
      <StyledAppBar position='static' color='inherit'>
        <Typography variant='h2' align='center'>
          Video Conferencing App
        </Typography>
      </StyledAppBar>
      <VideoPlayer />
      <Options>
        <Notification />
      </Options>
    </Wrapper>
  )
}

export default App

方案2:用 @emotion/css 生成类名(贴近 makeStyles 用法)

如果习惯类名管理模式,安装 @emotion/css 和 @emotion/react 后,用 css 函数生成类名:

import React from 'react';
import { Typography, AppBar } from '@mui/material';
import { css } from '@emotion/css';
import { useTheme } from '@mui/material/styles';
import VideoPlayer from './components/VideoPlayer';
import Options from './components/Options';
import Notification from './components/Notification';

const App = () => {
  const theme = useTheme();
  
  const classes = {
    wrapper: css({
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      width: '100%',
    }),
    appBar: css({
      borderRadius: 15,
      margin: '30px 100px',
      display: 'flex',
      flexDirection: 'row',
      justifyContent: 'center',
      alignItems: 'center',
      width: '600px',
      border: '2px solid black',
      [theme.breakpoints.down('xs')]: {
        width: '90%',
      },
    })
  };

  return (
    <div className={classes.wrapper}>
      <AppBar className={classes.appBar} position='static' color='inherit'>
        <Typography variant='h2' align='center'>
          Video Conferencing App
        </Typography>
      </AppBar>
      <VideoPlayer />
      <Options>
        <Notification />
      </Options>
    </div>
  )
}

export default App

方案3:使用 MUI sx 属性(最简方式)

直接通过组件自带的 sx 属性写样式,支持主题变量和响应式,无需额外依赖:

import React from 'react';
import { Typography, AppBar } from '@mui/material';
import VideoPlayer from './components/VideoPlayer';
import Options from './components/Options';
import Notification from './components/Notification';

const App = () => {
  return (
    <div sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '100%' }}>
      <AppBar 
        position='static' 
        color='inherit'
        sx={{
          borderRadius: 15,
          margin: '30px 100px',
          display: 'flex',
          flexDirection: 'row',
          justifyContent: 'center',
          alignItems: 'center',
          width: '600px',
          border: '2px solid black',
          // 移动端响应式
          ['@media (max-width:600px)']: {
            width: '90%',
          }
        }}
      >
        <Typography variant='h2' align='center'>
          Video Conferencing App
        </Typography>
      </AppBar>
      <VideoPlayer />
      <Options>
        <Notification />
      </Options>
    </div>
  )
}

export default App

内容的提问来源于stack exchange,提问作者idil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:35:00