Material UI:在 React 类组件中使用主题

IT技术 reactjs material-ui
2021-05-04 18:17:29

我正在寻找像 ThemeConsumer 这样的东西(可能不存在)。我有 React 组件,我正在使用withStyles()高阶组件来注入自定义样式。它在文档中得到了很好的描述,但我没有找到任何使用主题的示例。


我有一些包含ThemeProvider 的基本组件这意味着任何 MUI 组件都受到它的影响。

const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
const theme = getTheme(prefersDarkMode);
return (
   <ThemeProvider theme={theme}>
      ...
   </ThemeProvider>
)

我还使用一些功能组件makeStyles()来创建具有提供主题的样式。

const useStyles = makeStyles(theme => ({
   // here I can use theme provided by ThemeProvider
});

但是不能在类组件中使用所以我正在使用withStyles()HOC。

const styles = {
   // I would like to use here provided theme too
}
export default withStyles(styles)(SomeComponent);

我的问题摘要:
如何在类组件中使用提供的主题

3个回答

装饰的组件withStyles(styles)classes注入一个特殊的prop,它可以用于您的自定义样式。例如:

import { Box } from "@material-ui/core"
import { withStyles } from "@material-ui/core/styles"

const styles = theme => ({
  myCustomClass: {
    color: theme.palette.tertiary.dark
  }
})

class myComponent extends Component {
  render() {
    const { classes, theme } = this.props
    // In last line, you see we have passed `{ withTheme: true }` option
    // to have access to the theme variable inside the class body. See it
    // in action in next line.

    return <Box className={classes.myCustomClass} padding={theme.spacing(4)} />
  }
}

export default withStyles(styles, { withTheme: true })(myComponent)

如果您将{ withTheme: true }选项传递withStylesHOC,您也会将主题变量作为props注入。

如果您有其他 HOC(例如 Redux 的连接、路由器等)应用于您的组件,您可以像这样使用它:

export default withStyles(styles, { withTheme: true })(
   withRouter(connect(mapStateToProps)(myComponent))
)

关于这个主题的更全面的解释可以在这篇文章中找到:在 React 函数和类组件中使用 Material UI 主题变量

withStyles支持类似的语法makeStyles

const styles = theme => ({
   // here I can use theme provided by ThemeProvider
});
export default withStyles(styles)(SomeComponent);

这是一个简单的工作示例:

import React from "react";
import { withStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";

const StyledPaper = withStyles(theme => ({
  root: {
    backgroundColor: theme.palette.secondary.main
  }
}))(Paper);
export default function App() {
  return (
    <StyledPaper className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </StyledPaper>
  );
}

使用主题编辑 withStyles

使用withThemeHOC

文档中的修改示例

import { withTheme } from '@material-ui/core/styles';

class DeepChildRaw 
{
 /*...*/
  render()
  {
    return <span>{`spacing ${this.props.theme.spacing}`}</span>;
  }
}

const DeepChild = withTheme(DeepChildRaw);