Javascript 无效的钩子调用

Javascript 无效的钩子调用,javascript,reactjs,material-ui,Javascript,Reactjs,Material Ui,我目前正在学习ReactJS,并学习了一个教程,该教程帮助我在使用firebase进行网页身份验证和授权方面有了一个良好的开端。现在,我正在使用MaterialUI中的登录页面模板,并尝试将其与当前代码合并。我在显示网格等方面没有问题,但是我无法使样式正常工作,因为我在运行时遇到了这个无效的钩子调用错误。下面是signin类以及错误 import React, {Component} from 'react'; import {withRouter} from 'react-router-dom

我目前正在学习ReactJS,并学习了一个教程,该教程帮助我在使用firebase进行网页身份验证和授权方面有了一个良好的开端。现在,我正在使用MaterialUI中的登录页面模板,并尝试将其与当前代码合并。我在显示网格等方面没有问题,但是我无法使样式正常工作,因为我在运行时遇到了这个无效的钩子调用错误。下面是signin类以及错误

import React, {Component} from 'react';
import {withRouter} from 'react-router-dom';
import Avatar from '@material-ui/core/Avatar';
import Button from '@material-ui/core/Button';
import CssBaseline from '@material-ui/core/CssBaseline';
import TextField from '@material-ui/core/TextField';
import Link from '@material-ui/core/Link';
import Paper from '@material-ui/core/Paper';
import Box from '@material-ui/core/Box';
import Grid from '@material-ui/core/Grid';
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import {withFirebase} from "../Firebase";
import * as ROUTES from "../../constants/routes";
import {compose} from "recompose";

const SignInPage = () => (
    <div>
        <SignInForm />
    </div>
);

function Copyright() {
    return (
        <Typography variant="body2" color="textSecondary" align="center">
            {'Copyright © '}
            <Link color="inherit" href="https://material-ui.com/">
                Your Company Here
            </Link>{' '}
            {new Date().getFullYear()}
            {'.'}
        </Typography>
    );
}

const useStyles = makeStyles((theme) => ({
    root: {
        height: '100vh',
    },
    image: {
        backgroundImage: 'url(https://source.unsplash.com/random)',
        backgroundRepeat: 'no-repeat',
        backgroundColor:
            theme.palette.type === 'light'
                ? theme.palette.grey[50]
                : theme.palette.grey[900],
        backgroundSize: 'cover',
        backgroundPosition: 'center',
    },
    paper: {
        margin: theme.spacing(8, 4),
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
    },
    avatar: {
        margin: theme.spacing(1),
        backgroundColor: theme.palette.secondary.main,
    },
    form: {
        width: '100%', // Fix IE 11 issue.
        marginTop: theme.spacing(1),
    },
    submit: {
        margin: theme.spacing(3, 0, 2),
    },
}));

const INITIAL_STATE = {
    email: '',
    password: '',
    error: '',
}

class SignInFormBase extends Component {

    constructor(props) {
        super(props);

        this.state = {...INITIAL_STATE};
    }

    onSubmit = event => {
        const {email, password} = this.state;

        this.props.firebase
            .doSignInWithEmailAndPassword(email, password)
            .then(() => {
                this.setState({...INITIAL_STATE});
                this.props.history.push(ROUTES.HOME);
            })
            .catch(error => {
                this.setState({error});
            });

        event.preventDefault();
    };

    onChange = event => {
        this.setState({[event.target.name]: event.target.value});
    };

    render() {
        const classes = useStyles();

        return (
            <Grid container component="main" className={classes.root}>
                <CssBaseline />
                <Grid item xs={false} sm={4} md={7} className={classes.image} />
                <Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
                    <div className={classes.paper}>
                        <Avatar className={classes.avatar}>
                            <LockOutlinedIcon />
                        </Avatar>
                        <Typography component="h1" variant="h5">
                            Sign in
                        </Typography>
                        <form className={classes.form} noValidate>
                            <TextField
                                variant="outlined"
                                margin="normal"
                                required
                                fullWidth
                                id="email"
                                label="Email Address"
                                name="email"
                                autoComplete="email"
                                autoFocus
                            />
                            <TextField
                                variant="outlined"
                                margin="normal"
                                required
                                fullWidth
                                name="password"
                                label="Password"
                                type="password"
                                id="password"
                                autoComplete="current-password"
                            />
                            <Button
                                type="submit"
                                fullWidth
                                variant="contained"
                                className={classes.submit}
                            >
                                Sign In
                            </Button>
                            <Grid container>
                                <Grid item xs>
                                    <Link href="#" variant="body2">
                                        Forgot password?
                                    </Link>
                                </Grid>
                                <Grid item>
                                    <Link href="#" variant="body2">
                                        {"Don't have an account? Sign Up"}
                                    </Link>
                                </Grid>
                            </Grid>
                            <Box mt={5}>
                                <Copyright />
                            </Box>
                        </form>
                    </div>
                </Grid>
            </Grid>
        )
    }
}

const SignInForm = compose(
    withRouter,
    withFirebase,
)(SignInFormBase);

export default SignInPage;

export {SignInForm};

您必须重新编写基于类的组件,以尝试将hook
makeStyles
作为功能组件实现。在您的情况下,需要重新编写的组件是
SignInFormBase
。如何将基于类的组件转换为函数的问题在此之前已经得到了回答,因此您可以查看相关帮助。

您必须重新编写基于类的组件,尝试将hook
makeStyles
作为函数实现。在您的情况下,需要重新编写的组件是
SignInFormBase
。如何将基于类的组件转换成函数的问题已经在这里得到了解答,所以您可以在上面查看帮助。

检查一下,您不能在类类组件中使用钩子。您可以考虑重写为一个函数组件。检查一下,您不能在基于类的组件中使用钩子。可以考虑改写为一个功能组件-谢谢!这实际上帮助很大。我还没有真正了解React中的钩子,所以根据您的回答,我查阅了一些关于将类组件转换为钩子的文档。我将SignInfo数据库更改为一个钩子而不是类组件,现在我得到了完全符合我需要的样式。转换成钩子比我预期的要容易得多,尤其是设置和更新状态。谢谢!这实际上帮助很大。我还没有真正了解React中的钩子,所以根据您的回答,我查阅了一些关于将类组件转换为钩子的文档。我将SignInfo数据库更改为一个钩子而不是类组件,现在我得到了完全符合我需要的样式。转换成钩子比我预期的要容易得多,尤其是设置和更新状态。
const classes = useStyles();
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app