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

Material-UI:如何在makeStyles中通过ThemeProvider传递并使用theme?

解决方案:结合ThemeProvider与makeStyles实现组件主题化

我来帮你搞定这个问题!核心思路是利用makeStyles的回调参数自动获取当前ThemeProvider提供的主题,这样每个组件都能基于上层传递的主题定义自己的样式类,完全替代内联样式的写法。下面是完整的实现步骤和代码:

1. 定义两个主题

首先创建你需要的LeftSectionTheme和RightSectionTheme,这里用Material UI v5的createTheme(如果是v4版本,替换成createMuiTheme即可):

// themes.js
import { createTheme } from '@mui/material/styles';

// 左侧区域主题
export const LeftSectionTheme = createTheme({
  palette: {
    primary: {
      main: '#2e7d32', // 自定义绿色主色
    },
  },
  typography: {
    body1: {
      fontSize: '1.1rem',
    },
  },
});

// 右侧区域主题
export const RightSectionTheme = createTheme({
  palette: {
    primary: {
      main: '#1976d2', // 自定义蓝色主色
    },
  },
  typography: {
    body1: {
      fontSize: '1rem',
    },
  },
});

2. 改造LeftSection组件

用makeStyles创建样式类,并用ThemeProvider包裹内容,传递左侧主题:

// LeftSection.js
import React from 'react';
import { makeStyles } from '@mui/styles';
import { ThemeProvider } from '@mui/material/styles';
import { LeftSectionTheme } from './themes';
import Subsection from './Subsection';

// 基于当前主题定义样式
const useStyles = makeStyles((theme) => ({
  sectionContainer: {
    padding: theme.spacing(3),
    backgroundColor: theme.palette.grey[100],
    borderRadius: theme.shape.borderRadius,
  },
  sectionTitle: {
    color: theme.palette.primary.dark,
    marginBottom: theme.spacing(2),
  },
}));

function LeftSection() {
  const classes = useStyles();
  
  return (
    <ThemeProvider theme={LeftSectionTheme}>
      <div className={classes.sectionContainer}>
        <h2 className={classes.sectionTitle}>Left Section</h2>
        <Subsection />
      </div>
    </ThemeProvider>
  );
}

export default LeftSection;

3. 改造RightSection组件

和左侧逻辑一致,只是传递右侧主题:

// RightSection.js
import React from 'react';
import { makeStyles } from '@mui/styles';
import { ThemeProvider } from '@mui/material/styles';
import { RightSectionTheme } from './themes';
import Subsection from './Subsection';

const useStyles = makeStyles((theme) => ({
  sectionContainer: {
    padding: theme.spacing(3),
    backgroundColor: theme.palette.grey[200],
    borderRadius: theme.shape.borderRadius,
  },
  sectionTitle: {
    color: theme.palette.primary.dark,
    marginBottom: theme.spacing(2),
  },
}));

function RightSection() {
  const classes = useStyles();
  
  return (
    <ThemeProvider theme={RightSectionTheme}>
      <div className={classes.sectionContainer}>
        <h2 className={classes.sectionTitle}>Right Section</h2>
        <Subsection />
      </div>
    </ThemeProvider>
  );
}

export default RightSection;

4. 改造Subsection组件

删掉useTheme和内联样式,用makeStyles基于上层传递的主题定义样式:

// Subsection.js
import React from 'react';
import { makeStyles } from '@mui/styles';

const useStyles = makeStyles((theme) => ({
  subsectionText: {
    color: theme.palette.primary.main,
    fontSize: theme.typography.body1.fontSize,
    fontWeight: theme.typography.fontWeightMedium,
    lineHeight: 1.6,
  },
}));

function Subsection(props) {
  const classes = useStyles();
  
  return (
    <p className={classes.subsectionText}>
      test
    </p>
  );
}

export default Subsection;

关键说明

  • makeStyles的回调函数会自动接收当前ThemeProvider提供的主题对象,所以不管是LeftSection、RightSection还是它们内部的Subsection,都能拿到对应的主题属性。
  • ThemeProvider是层级生效的,内部组件会继承最接近的上层ThemeProvider的主题,所以Subsection在左侧区域会用LeftSectionTheme,在右侧区域会用RightSectionTheme。
  • 如果你的项目是Material UI v4版本,只需要把导入路径替换成@material-ui/core/styles和@material-ui/styles,createTheme换成createMuiTheme即可,逻辑完全一致。

内容的提问来源于stack exchange,提问作者Gal Grünfeld

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:56:32