Recibo el siguiente error cada vez que trato de usar makeStyles() con un componente con métodos de ciclo de vida:
Llamada de gancho no válida. Los ganchos solo se pueden llamar dentro del cuerpo de un componente de función. Esto podría suceder por una de las siguientes razones:
- Es posible que tenga versiones que no coincidan de React y el renderizador (como React DOM)
- Podrías estar rompiendo las Reglas de los Hooks
- Es posible que tenga más de una copia de React en la misma aplicación
A continuación se muestra un pequeño ejemplo de código que produce este error. Otros ejemplos también asignan clases a elementos secundarios. No puedo encontrar nada en la documentación de MUI que muestre otras formas de usar makeStyles y tenga la capacidad de usar métodos de ciclo de vida.
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;Hola, en lugar de usar la API de enlace, debe usar la API de componente de orden superior como se menciona aquí
Modificaré el ejemplo en la documentación para adaptarlo a su necesidad de componente de clase.
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);withStyles en lugar de 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)Lo que terminamos haciendo fue dejar de usar los componentes de clase y crear componentes funcionales, usando useEffect() de la API de Hooks para métodos de ciclo de vida . Esto le permite seguir usando makeStyles() con métodos de ciclo de vida sin agregar la complicación de crear componentes de orden superior . Que es mucho más simple.
Ejemplo:
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;