Как стилизовать компоненты, используя makeStyles, и при этом все еще использовать методы жизненного цикла в пользовательском интерфейсе материалов?
Я получаю приведенную ниже ошибку всякий раз, когда пытаюсь использовать makeStyles
с компонентом с методами жизненного цикла (то есть компонентом класса):
Неверный вызов крюка. Хуки могут быть вызваны только внутри тела функционального компонента. Это может произойти по одной из следующих причин:
- У вас могут быть несовпадающие версии React и средства визуализации (например, React DOM)
- Возможно, вы нарушаете правила крючков
- В одном приложении может быть несколько копий 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);