【问题标题】:How do I create css class in createMuiTheme() and use them directly without having to get its value from component "classes" props?如何在 createMuiTheme() 中创建 css 类并直接使用它们,而无需从组件“类”道具中获取其值?
【发布时间】:2019-05-29 09:51:01
【问题描述】:

我试图避免输入多余的代码。在多个组件中,我创建了相同的 css 类。我想使用 createMuiTheme() 将它们添加到主题中,然后只直接使用主题中的样式,而不必在 Component 道具上调用“类”道具。

我尝试在根组件上创建一个主题,如下所示:

const theme = createMuiTheme({
  palette:{
      primary: {
        main: '#47286E',
        light: '#D91677'
      },
      secondary: {
        main: '#9156D8' 
      },
  },

 fab: {
    position: "relative",
    top: 0,
    marginTop: 20px
    textTransform: 'none',
    width: 220,
    height: 50
  },

});

然后我将主题传递给其他组件使用

<MuiThemeProvider theme={theme}>

我尝试直接在组件中导入 fab 按钮

<Fab variant="extended" className={this.props.theme.fab} size='small'>
    Change
</Fab>

但是,当我尝试获取 fab css 类时,我似乎没有得到任何价值。我只是不想创造一个全新的

const styles = theme => {
    blabbla
}

如果我想要的主题已经在传递给其子组件的主题上,则使用“类”道具将其导入每个组件。

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    这些都是很好的答案。我正在做笔记 :) 当我第一次阅读这篇文章时,我怀疑直觉是在内置 MUI 主题中使用 overrides 键。

    我经常发现 overrides 键是一种更方便的方式来实现应用中“更频繁”使用的格式。

    这是一个两步过程:

    1. 决定要修改哪个 MUI 组件
    2. 使用适合您的命名约定设置 className 属性
    import clsx from 'clsx'; // not required, but handy in the long-run
    import Fab from '@material-ui/core/Fab';
    
    const Component = () => {
      ...
      return <Fab className=clsx('MyCustomFab') />
    }
    
    // my theme prop for the MUI <ThemeProvider theme={myTheme} />
    
    export default createMuiTheme({
      ...
      overrides: {
        MuiFab: {
          root: {
            '&.MyCustomFab': { // note: the "no-space" => MuiFab AND ...
              backgroundColor: "lightblue",
            }
          }
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      我认为createMuiTheme 不是为此而生的。

      或者,您可以只创建一个您想要重用的样式对象

      const styles = {
        fab: {
          position: "relative",
          top: 0,
          marginTop: 20px
          textTransform: 'none',
          width: 220,
          height: 50
        }
      };
      

      只需在需要的地方导入并使用它

      import fabStyles from '../../somewhere-everyone-can-get-it.js';
      import styles from './styles-for-this-component.js';
      
      ...
      
      withStyles({...fabStyles, ...styles})(Component);
      

      如果您需要主题和样式。

      withTheme(withStyles({...fabStyles, ...styles})(Component));
      

      您也可以使用recompose 来清理它。

      【讨论】:

      • 但我如何才能访问这些单独文件中的主题变量?
      • 我没有看到您在示例中使用主题样式,但除了withStyles之外,您还可以使用withTheme HOC
      • 你能举个例子吗?我仍然掌握使用 HOC 的窍门……谢谢!
      • 更新答案:)
      • 对不起@Galupuf,但是当我这样使用它时: withRouter(withTheme(withStyles({...defaultStyles, ...styles})(TableCustom)));由于某种原因,它停止显示整个组件。
      【解决方案3】:

      className={this.props.theme.fab} 不起作用,因为this.props.theme.fab 是一个对象,而不是类名。当使用withStyles 时,它负责生成一个唯一的类名(例如,可通过props.classes.fab 获得)以及将该类的CSS 注入文档的头部。您主题中的 fab 对象尚未完成这项工作。

      下面的代码显示了避免冗余代码的几种方法。第一个是 withFab 函数,它封装了 CSS 和对 withStyles 的调用。

      第二个更直接地使用fab 对象并将其传递给style 属性而不是className 属性。您可以从 theme.fab (而不是单独的 js 文件)中获取类似于您最初方法的样式,但不一定有理由将其放入您的主题中,除非您关心能够通过不同的 @987654334 覆盖它@ 在你的渲染层次结构中。

      第二种(样式属性)方法有几个缺点:

      • 如果您在许多不同的元素上使用它,则 CSS 会在 DOM 中对每个元素进行冗余指定。
      • 它不支持需要类的 CSS(例如,使用 :hover 之类的伪元素)

      所以我会推荐一些更类似于下面显示的第一个选项 (UseWithFab/withFab) 的东西。

      withFab.js

      import withStyles from "@material-ui/core/styles/withStyles";
      
      const styles = {
        fab: {
          backgroundColor: "lightblue"
        }
      };
      export const fabStyles = {
        backgroundColor: "lightgreen"
      };
      const withFab = component => {
        return withStyles(styles)(component);
      };
      export default withFab;
      

      index.js

      import React from "react";
      import ReactDOM from "react-dom";
      import withFab, { fabStyles } from "./withFab";
      
      const UseWithFab = withFab(props => {
        return <div className={props.classes.fab}>Using withFab</div>;
      });
      const UseFabStyles = props => {
        return <div style={fabStyles}>Using fabStyles</div>;
      };
      function App(props) {
        return (
          <>
            <UseWithFab />
            <UseFabStyles />
          </>
        );
      }
      const rootElement = document.getElementById("root");
      ReactDOM.render(<App />, rootElement);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-09
        • 2021-01-12
        • 1970-01-01
        • 2011-10-05
        相关资源
        最近更新 更多