如何使用 useStyle 在 Material Ui 中设置类组件的样式

Posted

技术标签:

【中文标题】如何使用 useStyle 在 Material Ui 中设置类组件的样式【英文标题】:How to use useStyle to style Class Component in Material Ui 【发布时间】:2019-10-26 12:26:36 【问题描述】:

我想使用 useStyle 来设置 Class Component 的样式。但这可以很容易地完成钩子。但我想改用组件。但我不知道该怎么做。

import React,Component from 'react';
import Avatar from '@material-ui/core/Avatar';
import  makeStyles  from '@material-ui/core/styles';
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';


    const useStyles = makeStyles(theme => (
      '@global': 
        body: 
          backgroundColor: theme.palette.common.white,
        ,
      ,
      paper: 
        marginTop: theme.spacing(8),
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
      ,
      avatar: 
        margin: theme.spacing(1),
        backgroundColor: theme.palette.secondary.main,
      
));

class SignIn extends Component
  const classes = useStyle(); // how to assign UseStyle
  render()
     return(
    <div className=classes.paper>
    <Avatar className=classes.avatar>
      <LockOutlinedIcon />
    </Avatar>
    </div>
  

export default SignIn;

【问题讨论】:

你漏掉了括号,应该是 const classes = useStyle(); 【参考方案1】:

你可以这样做:

import  withStyles  from "@material-ui/core/styles";

const styles = theme => (
  root: 
    backgroundColor: "red"
  
);

class ClassComponent extends Component 
  state = 
    searchNodes: ""
  ;

  render() 
    const  classes  = this.props;
    return (
      <div className=classes.root>Hello!</div>
    );
  


export default withStyles(styles,  withTheme: true )(ClassComponent);

如果您不使用主题,请忽略 withTheme: true


要使其在 TypeScript 中工作,需要进行一些更改:

import  createStyles, withStyles, WithStyles  from "@material-ui/core/styles";

const styles = theme => createStyles(
  root: 
    backgroundColor: "red"
  
);

interface Props extends WithStyles<typeof styles> 

class ClassComponent extends Component<Props> 

// the rest of the code stays the same

【讨论】:

Material UI 中使用高阶组件 API 的官方示例:material-ui.com/styles/basics/#higher-order-component-api 谢谢。 正如我所尝试的,即使我们有主题,我们也不需要 withTheme: true 我们需要但不值得的英雄!我们已经远离了基于类的组件,与 React.FC 相比,它们是一团糟,但是要使模态与 Material-UI 一起工作,我们必须使用基于类的组件。这与 Typescript 完美配合。 不幸的是,这似乎与 TypeScript 中的 refs 不兼容。以前我可以使用useRef&lt;MyComponent&gt;(null) 对组件进行引用,但他不再有效,因为MyComponent 不再是一种类型。更令人不安的是,TypeScript 报告从 withStyles()() 返回的组件上的“属性 'ref' 不存在”,但涉及 any 的丑陋 hack 使错误消失,代码似乎工作。【参考方案2】:

对于类组件,您可以使用withStyles 而不是makeStyles

import  withStyles  from '@material-ui/core/styles';

const useStyles = theme => (
fab: 
  position: 'fixed',
  bottom: theme.spacing(2),
  right: theme.spacing(2),
,
  );

class ClassComponent extends Component 
   render() 
            const  classes  = this.props;

            /** your UI components... */
      
 


export default withStyles(useStyles)(ClassComponent)

【讨论】:

我也遇到过同样的问题,听从了你的建议,但是没有样式的道具是空的。有小费吗?谢谢。【参考方案3】:

嘿,我遇到了类似的问题。我通过将makeStyles 替换为withStyles 来解决它,然后在执行const classes = useStyle(); 之类的操作时,将其替换为const classes = useStyle;

您注意到useStyle 不应该是函数调用,而是变量赋值。

在您进行这些更改后应该可以正常工作。

【讨论】:

【参考方案4】:

useStyles 是一个反应钩子。只能在函数组件中使用。

这一行创建了钩子:

const useStyles = makeStyles(theme => ( /* ... */ );

您在函数组件中使用它来创建类对象:

const classes = useStyles();

然后在 jsx 中使用类:

<div className=classes.paper>

推荐资源: https://material-ui.com/styles/basics/ https://reactjs.org/docs/hooks-intro.html

【讨论】:

类组件可以使用withStyles 在此答案链接的文档中,它位于“高阶组件 API”标题下。【参考方案5】:

就像已经说明的其他答案一样,您应该使用withStyles 来扩充组件并通过属性传递classes。我冒昧地将Material-UI stress test example 修改为使用类组件的变体。

请注意,当您只想使用样式时,通常不需要withTheme: true 选项。本例中需要它,因为在渲染中使用了主题的实际值。设置此选项使theme 通过类属性可用。应始终提供 classes 属性,即使未设置此选项也是如此。

const useStyles = MaterialUI.withStyles((theme) => (
  root: (props) => (
    backgroundColor: props.backgroundColor,
    color: theme.color,
  ),
), withTheme: true);

const Component = useStyles(class extends React.Component 
  rendered = 0;

  render() 
    const classes, theme, backgroundColor = this.props;
    return (
      <div className=classes.root>
        rendered ++this.rendered times
        <br />
        color: theme.color
        <br />
        backgroundColor: backgroundColor
      </div>
    );
  
);

function StressTest() 
  const [color, setColor] = React.useState('#8824bb');
  const [backgroundColor, setBackgroundColor] = React.useState('#eae2ad');

  const theme = React.useMemo(() => ( color ), [color]);
  const valueTo = setter => event => setter(event.target.value);

  return (
    <MaterialUI.ThemeProvider theme=theme>
      <div>
        <fieldset>
          <div>
            <label htmlFor="color">theme color: </label>
            <input
              id="color"
              type="color"
              onChange=valueTo(setColor)
              value=color
            />
          </div>
          <div>
            <label htmlFor="background-color">background-color property: </label>
            <input
              id="background-color"
              type="color"
              onChange=valueTo(setBackgroundColor)
              value=backgroundColor
            />
          </div>
        </fieldset>
        <Component backgroundColor=backgroundColor />
      </div>
    </MaterialUI.ThemeProvider>
  );


ReactDOM.render(<StressTest />, document.querySelector("#root"));
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@material-ui/core@4/umd/material-ui.production.min.js"></script>
<div id="root"></div>

【讨论】:

【参考方案6】:

还有另一种方法可以做到这一点,尽管有点变通方法。

有些人可能会说这并不能真正回答问题,但我认为确实如此。最终结果是 useStyles() 为基于类的多部分父组件提供样式。

在我的例子中,我需要一个标准的 javascript 类导出,这样我就可以调用 new MyClass() 而不会出现 MyClass is not a constructor 错误。

import  Component  from "./react";
import  makeStyles  from "@material-ui/core/styles";

const useStyles = makeStyles((theme) => (
  someClassName: 
    ...
  
));

export default class MyComponent extends Component 
  render() 
    return <RenderComponent ...this.props />;
  


function RenderComponent(props) 
  const classes = useStyles();

  return (
    /* JSX here */
  );

【讨论】:

【参考方案7】:

如何使用类组件在 ClassName 中添加多个类

import  withStyles  from "@material-ui/core/styles";

const styles = theme => (
  root: 
    backgroundColor: "red"
  ,
  label: 
    backGroundColor:"blue"
 
);

class ClassComponent extends Component 
  state = 
    searchNodes: ""
  ;

  render() 
    const  classes  = this.props;//   
    return (
      <div className=classes.root + classes.label>Hello!</div> //i want to add label style also with
    );
  

【讨论】:

以上是关于如何使用 useStyle 在 Material Ui 中设置类组件的样式的主要内容,如果未能解决你的问题,请参考以下文章

Material UI 无效的钩子调用

分隔线颜色变化 React Material Ui

NextJs/Material-ui 不尊重 makeStyles CSS

ReferenceError:在初始化React Collapse Component之前无法访问词法声明'useStyles',axios获取数据材料ui useStyles

在材质 ui usestyles 中使用兄弟组合器

MUI v5 使用 styled() 将道具传递给 CSS 主题