当前位置: 首页 > 知识库问答 >
问题:

如何使用makeStyles设置组件样式,并且在材质UI中仍然具有生命周期方法?

柳梓
2023-03-14

每当我尝试将makeStyles()与具有生命周期方法的组件一起使用时,就会出现以下错误:

无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一:

  1. React和渲染器的版本可能不匹配(例如React DOM)
  2. 你可能违反了钩子的规则
  3. 同一应用程序中可能有多个React副本

下面是产生此错误的代码的一个小示例。其他示例也将类分配给子项。我在MUI的文档中找不到任何显示使用makeStyles的其他方法以及使用生命周期方法的能力的内容。

    import React, { Component } from 'react';
    import { Redirect } from 'react-router-dom';

    import { Container, makeStyles } from '@material-ui/core';

    import LogoButtonCard from '../molecules/Cards/LogoButtonCard';

    const useStyles = makeStyles(theme => ({
      root: {
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
      },
    }));

    const classes = useStyles();

    class Welcome extends Component {
      render() {
        if (this.props.auth.isAuthenticated()) {
          return <Redirect to="/" />;
        }
        return (
          <Container maxWidth={false} className={classes.root}>
            <LogoButtonCard
              buttonText="Enter"
              headerText="Welcome to PlatformX"
              buttonAction={this.props.auth.login}
            />
          </Container>
        );
      }
    }

    export default Welcome;

共有3个答案

慕容光启
2023-03-14

我们最终停止使用类组件,并使用生命周期方法的Hooks API中的useffect()创建功能组件。这允许您仍然将makeStyles()与生命周期方法结合使用,而不增加制作高阶组件的复杂性。这要简单得多。

例子:

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Redirect } from 'react-router-dom';

import { Container, makeStyles } from '@material-ui/core';

import LogoButtonCard from '../molecules/Cards/LogoButtonCard';

const useStyles = makeStyles(theme => ({
  root: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    margin: theme.spacing(1)
  },
  highlight: {
    backgroundColor: 'red',
  }
}));

// Highlight is a bool
const Welcome = ({highlight}) => { 
  const [userName, setUserName] = useState('');
  const [isAuthenticated, setIsAuthenticated] = useState(true);
  const classes = useStyles();

  useEffect(() => {
    axios.get('example.com/api/username/12')
         .then(res => setUserName(res.userName));
  }, []);

  if (!isAuthenticated()) {
    return <Redirect to="/" />;
  }
  return (
    <Container maxWidth={false} className={highlight ? classes.highlight : classes.root}>
      <LogoButtonCard
        buttonText="Enter"
        headerText={isAuthenticated && `Welcome, ${userName}`}
        buttonAction={login}
      />
   </Container>
   );
  }
}

export default Welcome;
邵骏喆
2023-03-14

我使用了带有样式的而不是makeStyle

EX:

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

const useStyles = theme => ({
        root: {
           flexGrow: 1,
         },
  });

class App extends Component {
       render() {
                const { classes } = this.props;
                return(
                    <div className={classes.root}>
                       Test
                </div>
                )
          }
} 

export default withStyles(useStyles)(App)

宦兴朝
2023-03-14

您好,您应该使用这里提到的高阶组件API,而不是使用钩子API

我将修改文档中的示例,以满足您对类组件的需求

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/styles';
import Button from '@material-ui/core/Button';

const styles = theme => ({
  root: {
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    border: 0,
    borderRadius: 3,
    boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
    color: 'white',
    height: 48,
    padding: '0 30px',
  },
});

class HigherOrderComponentUsageExample extends React.Component {
  
  render(){
    const { classes } = this.props;
    return (
      <Button className={classes.root}>This component is passed to an HOC</Button>
      );
  }
}

HigherOrderComponentUsageExample.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(HigherOrderComponentUsageExample);
 类似资料:
  • 我一直在试图找出如何样式的材料ui TextField组件。 我的类创建如下: 我的问题是,我似乎无法让文本字段的颜色变成白色。我似乎能够将样式应用于整个文本字段(因为宽度样式工作等)...但是我认为问题是我没有将样式应用到链的更下游和实际输入中。 我曾试图寻找其他关于传递输入道具的答案,但没有成功。 我已经尽了我最大的努力,但我想我需要问问是否有人知道我做错了什么。 它现在看起来是什么样子

  • 一般来说,一个组件类由 extends Component 创建,并且提供一个 render 方法以及其他可选的生命周期函数、组件相关的事件或方法来定义。 {% include './share/simple-component.md' %} getInitialState 初始化 this.state 的值,只在组件装载之前调用一次。 如果是使用 ES6 的语法,你也可以在构造函数中初始化状态,

  • 我想从材质UI更改(减少)工具栏的默认高度 我已经提到了如何更改材质UI工具栏高度?但我仍然面临着这个问题 问题是,当我超过50岁时,我能看到变化。但当我想降低高度时,我无法做到。 我如何才能实现这一点? 我的代码:

  • 我试图通过编程将焦点设置在(激活)材质ui中菜单组件内的一个菜单项上。我可以通过切换到它来手动完成,但我需要通过编程来响应按键关闭事件。

  • 问题内容: 在Material UI中,我想在按钮上设置borderRadius。传递属性似乎适用于,但不适用于。 对于,borderRadius应用于父对象(这是必需的),而不是自身(也是必需的) 这是Material UI中的错误吗?还是这种行为是故意的?如果需要,那么如何制作带有圆角的RaisedButton? 问题答案: 这是预期的行为,并在docs中这样说。作为记录,您永远不希望将道具传

  • 我已经通过了在反应v16.7.0中引入的钩子。 https://reactjs.org/docs/hooks-intro.html 所以我对钩子的理解是,我们可以在函数组件中使用状态,而不用在反应中编写类组件。这真是惊人的功能。 但是我没有清楚地了解在功能组件中使用钩子的情况。 如果使用钩子,如何在上述功能组件中使用生命周期方法?