【问题标题】:How to pass className style to sub component in `material-ui`?如何将className样式传递给`material-ui`中的子组件?
【发布时间】:2019-05-21 01:44:58
【问题描述】:

Material UI 使用className 进行样式设置。但是如何将样式传递给子反应组件?

以下是我的风格定义。

const styles = createStyles({
      root: {
        backgroundColor: 'transparent !important',
        boxShadow: 'none',
        paddingTop: '25px',
        color: '#FFFFFF'
      },
      subComponentStyle: {
         ...
      }
    });

我会这样使用:

...
const NavigationBar = (props) => {
   const { classes } = props;
   return ( 
       <div className={classes.root}>
        // Add other code here
          <SubComponent ... > // how to pass `classes.subComponentStyle` style here
       </div>
   )
}
...
export default withStyles(styles)(NavigationBar);

如果SubComponent 组件也使用withStyles 导出。如何传递一些样式来覆盖它自己的样式?

我的SubComponent 导出为:

const styles = createStyles({
   ...
});

const SubComponent = ({classes}) => {
...
}

export default withStyles(styles)(SubComponent);

如您所见,它有自己的classes。我不想完全覆盖它的类。有没有办法将传入的类与其内部类合并?

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    // 编辑为合并样式

    如果你传递类以及用样式包装子元素,MUI 将合并样式。即:

    import { styles } from './NavStyles'
    
    const NavigationBar = (props) => {
       const { classes } = props;
       return ( 
           <div className={classes.root}>
              <SubComponent classes={classes} >
           </div>
       )
    };
    
    export default withStyles(styles)(NavigationBar);
    

    然后也将样式应用到子组件

    
    import { styles } from './SubCompStyles'
    
    const SubComponent = ({classes}) => {
     // classes object is a merge of both parent and child styles
     // ... component logic
    };
    
    export default withStyles(styles)(SubComponent)
    

    【讨论】:

    • 我的SubComponent 也有自己的classes。我不想完全覆盖 SubComponent 样式。有没有办法将传入的类与内部类合并?
    • 在此答案中使用第二种方法时,这些类应自动与内部类通过withStyles 合并(通过子组件的classes 属性传递classes)。
    • 我刚刚尝试了@RyanCogswell 的解决方案 - 并且可以确认它们确实合并了。
    • 当您使用打字稿并且两种类型不匹配时,这应该如何工作?
    • 它将显示 警告:Material-UI:提供给类属性对象的键 xxx 未在 SubComponent 中实现。 如果 NavigationBar && SubComponent 类对象键未实现同步。根据link,我建议使用 在这种情况下不要合并类。
    【解决方案2】:

    以下是使用钩子 API 的方法:

    子组件

    const useStyles = makeStyles((theme) => ({
      root: {
        borderRadius: 3,
        color: 'white',
        padding: '0 30px',
        width: '12em',
        height: 43,
        borderRadius: 21.5,
        textTransform: 'capitalize',
      ... your styles here. 
      },
    }))
    
    export default function AuthSecondaryButton(props) {
      const classes = useStyles()
      console.log('s', props.className)
      return (
        <Button
          {...props}
          className={clsx({
            [classes.root]: true,
            [props.className]: true,
          })}
        />
      )
    }
    

    父组件

    const useStyles = makeStyles((theme) => ({
    
     secondaryButton: {
        marginTop: theme.spacing(1),
      },
    }))
    
    
    export default function App(props) {
      const classes = useStyles()
    return(
      <AuthSecondaryButton
                  onClick={onClickSecondaryButton}
                  className={classes.secondaryButton}
                >
                  Sign Up
                </AuthSecondaryButton>
    )
    
    

    【讨论】:

      【解决方案3】:

      对@clever_usernames 方法稍作调整。 这使用classnames 包而不是我们在项目中使用的clsx 包。

      替换这个...

         className={clsx({
              [classes.root]: true,
              [props.className]: true,
            })}
      

      有了这个……

      className={classNames(classes.root, props.className)}
      

      完整示例

      子组件

      import classNames from 'classnames'
      
      const useStyles = makeStyles((theme) => ({
        root: {
          borderRadius: 3,
          color: 'white',
          padding: '0 30px',
          width: '12em',
          height: 43,
          borderRadius: 21.5,
          textTransform: 'capitalize',
        ... your styles here. 
        },
      }))
      
      export default function AuthSecondaryButton(props) {
        const classes = useStyles()
        console.log('s', props.className)
        return (
          <Button
            {...props}
            className={classNames(classes.root, props.className)}
          />
        )
      }
      
      

      父组件

      const useStyles = makeStyles((theme) => ({
      
       secondaryButton: {
          marginTop: theme.spacing(1),
        },
      }))
      
      
      export default function App(props) {
        const classes = useStyles()
      return(
        <AuthSecondaryButton
                    onClick={onClickSecondaryButton}
                    className={classes.secondaryButton}
                  >
                    Sign Up
                  </AuthSecondaryButton>
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-30
        • 2020-02-15
        • 1970-01-01
        • 2018-11-24
        • 2021-01-23
        • 2021-05-30
        • 1970-01-01
        • 2021-09-11
        相关资源
        最近更新 更多