Как стилизовать компоненты, используя makeStyles, и при этом все еще использовать методы жизненного цикла в пользовательском интерфейсе материалов?

Я получаю приведенную ниже ошибку всякий раз, когда пытаюсь использовать 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;

Ответ 1

Вы придерживаетесь materialui4.x's и используете materialui 3.x В 3.x есть метод withStyles. Это работает, если вы хотите использовать реагировать как класс. Если вы хотите использовать хуки, тогда вам не следует определять класс.

https://github.com/mui-org/material-ui/blob/master/docs/src/pages/components/selects/SimpleSelect.js этот пример пользовательского интерфейса следует materailui4.x и реагирует на хуки

Ответ 2

В итоге мы перестали использовать компоненты класса и создали функциональные компоненты, используя useEffect() из Hooks API для методов жизненного цикла. Это позволяет вам по-прежнему использовать makeStyles() с методами жизненного цикла , не добавляя усложнения создания компонентов высшего порядка. Что гораздо проще.

Пример:

import React, { useEffect, useState } 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();

const Welcome = () => {
  const [userName, setUserName] = useState('');
  const [isAuthenticated, setIsAuthenticated] = useState(true);

  useEffect(() => {
    // Stuff you'd normally execute using ComponentDidMount here like an API call
  }, []);

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

export default Welcome;

Ответ 3

Привет, вместо использования подключаемого 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 HigherOrderComponent extends React.Component {

  render(){
    const { classes } = this.props;
    return (
      <Button className={classes.root}>Higher-order component</Button>
      );
  }
}

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

export default withStyles(styles)(HigherOrderComponent);