JSS 嵌套样式容器

Posted

技术标签:

【中文标题】JSS 嵌套样式容器【英文标题】:JSS nested styles container 【发布时间】:2018-09-12 21:18:23 【问题描述】:

我正在使用 React Material UI -> TextField 组件,我想围绕它做一些包装,以覆盖样式。 根据文档,我们有 2 个道具来实现这一点: 1) InputProps - 这里我们应该将 classes 传递到内部的 Input 组件中,这是我们 TextField 的核心。 2) 直接 classes 属性,应该直接应用于 TextField。并且该类应该包含FormControl的规则

(听起来很难,实际上是在使用 Material UI =) 时)

无论如何,我想做这样的事情

import  withStyles  from 'material-ui/styles';

export const TextInputCSSCreator = theme => (
    "FormControlClasses" : 
        "root" :  "color" : "red 
       
    "InputClasses" : 
       "underline" : 
           "&:after" : 
               backgroundColor : "red",
           ,
       
    

);

<TextField
                classses=this.props.classes.FormControlClasses
                id=this.props.id
                InputProps=
                    classes : this.props.classes.InputClasses
                
                label=this.props.label
                value=this.state.value
                onChange=this._onValueChange
                margin=this.props.margin
            />

export default withStyles(TextInputCSSCreator)(TextInput);

在这里,我希望有可能将整个对象传递给我的 2 个目标。输入和表单控件。 但这是主要问题,我不知道如何解决。看起来 JSS(与 MaterialUi 中的 withStyles 相同)不适用于包含规则嵌套容器的对象。

我通过这种丑陋的方式完成了这项任务。它看起来像地狱,但我没有找到任何方法来避免它。有人可以帮我吗?实现这一要求真的只有一种方法吗?

因为我想要实现的方式为我们提供了灵活性,我们可以随时添加我们想要的任何类,而在第二种方式(如下)我们必须在开始时硬编码所有可能的类

顺便说一句。我想提供一种机制来从外部应用程序更改我的组件的样式,这就是为什么我不能在输出中使用 CSS,因为它应该是有效的 commonJS 模块。

export const TextInputCSSCreator = theme => (
    "FormControlRoot" : ,
    "FormControlMarginNormal" : ,
    "FormControlMarginDense" : ,
    "FormControlFullWidth" : ,

    "InputRoot" : ,
    "InputFormControl" : ,
    "InputFocused" : ,
    "InputDisabled" : ,
    "InputUnderline" : 
        "&:after" : 
            backgroundColor : "red",
        ,
    ,
    "InputError" : ,
    "InputMultiline" : ,
    "InputFullWIdth" : ,
    "InputInput" : ,
    "InputInputMarginDense" : ,
    "InputInputDisabled" : ,
    "InputInputMultiline" : ,
    "InputInputType" : ,
    "InputInputTypeSearch" : 
);

render() 
        const  classes  = this.props;
        return (

            <TextField
                classes=
                    root : classes.FormControlRoot,
          marginNormal : classes.FormControlMarginNormal,
                    marginDense : classes.FormControlMarginDense,
                    fullWidth : classes.FormControlFullWidth,
                
                id=this.props.id
                InputProps=
                    classes : 
                        root : classes.InputRoot,
                        formControl : classes.InputFormControl,
                        focused : classes.InputFocused,
                        disabled : classes.InputDisabled,
                        underline : classes.InputUnderline,
                        error : classes.InputError,
                        multiline : classes.InputMultiline,
                        fullWidth : classes.InputFullWIdth,
                        input : classes.InputInput,
                        inputMarginDense : classes.InputInputMarginDense,
                        inputDisabled : classes.InputInputDisabled,
                        inputMultiline : classes.InputInputMultiline,
                        inputType : classes.InputInputType,
                        inputTypeSearch : classes.InputInputTypeSearch
                    
                
                label=this.props.label
                value=this.state.value
                onChange=this._onValueChange
                margin=this.props.margin
            />


        );
    

export default withStyles(TextInputCSSCreator)(TextInput);

【问题讨论】:

【参考方案1】:

在这种情况下,我会做的是使用 createMuiTheme() 在单独的文件中为此组件创建主题,并将其应用于具有 MuiTheme 提供程序组件的组件。 经验:

import  createMuiTheme  from 'material-ui/styles';
const customTheme = createMuiTheme(
    overrides: 
        MuiInput: 
            root:
                color: 'red',
            ,
            underline: 
                    '&:after': 
                      backgroundColor: '#000000',
                    
              ,
        ,
    

);
export default customTheme;

然后像这样在我的组件上使用它:

<MuiThemeProvider theme = customTheme>
[Your component]
</MuiThemeProvider>

希望这会有所帮助!

【讨论】:

嗨。谢谢你的回答。但是,如果我想要一些看起来与主题控制的其他组件不同的组件怎么办? 您可以为不同的组件使用不同的主题,我将 App.js 包装在 中进行测试,并将其中一个子组件包装在自己的 customTheme 中。在这种情况下,子组件只有 customTheme 提供的样式,而没有从 globalTheme 继承任何东西。 但是将每个组件包装到他们自己的主题提供程序中看起来像是一种开销。我猜它可能会降低应用程序的性能,不是吗? 如果我有一个可以满足我大部分需求的全局主题,我会使用这种方法,如果我需要一个特殊的对话框,我会创建自己的主题并保存它。现在我不会滥用它,以至于每个组件都有自己的主题,某些东西可以通过类和样式等进行更改。就性能而言,这是需要测试的东西,据我了解它不应该比每次都用Styles() 重写样式要糟糕得多。

以上是关于JSS 嵌套样式容器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 material-ui 样式/JSS 中选择 id?

如何使用 cssinjs/jss 在 shadow root 中挂载样式

如何使用 JSS 为没有类的输入标签设置样式

React 的样式化组件 vs jss vs 情感

如何使用 JSS 设置 Material-UI 菜单弹出框的样式?

如何在 JSS 中使用子选择器