首页 > 解决方案 > React / MUI:如何在主 App.js 中使用钩子按钮调用其他类

问题描述

我是 React/MUI 的新手。我现在正在为网站创建不同的组件,所以现在的 UI 并不重要。

我在尝试使用按钮将我链接到注册页面时遇到了这个问题(对登录执行相同的操作):

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

以下是我的代码:

注册.js

import React from 'react';
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 FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import Link from '@material-ui/core/Link';
import Grid from '@material-ui/core/Grid';
import Box from '@material-ui/core/Box';
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import Container from '@material-ui/core/Container';

const useStyles = makeStyles((theme) => ({
    paper: {
        marginTop: theme.spacing(8),
        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(3),
    },
    submit: {
        margin: theme.spacing(3, 0, 2),
    },
}));

export default function SignUp() {
    const classes = useStyles();

    return (
        <Container component="main" maxWidth="xs">
            <CssBaseline />
            <div className={classes.paper}>
                <Avatar className={classes.avatar}>
                    <LockOutlinedIcon />
                </Avatar>
                <Typography component="h1" variant="h5">
                    Sign up
        </Typography>
                <form className={classes.form} noValidate>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sm={6}>
                            <TextField
                                autoComplete="fname"
                                name="firstName"
                                variant="outlined"
                                required
                                fullWidth
                                id="firstName"
                                label="First Name"
                                autoFocus
                            />
                        </Grid>
                        <Grid item xs={12} sm={6}>
                            <TextField
                                variant="outlined"
                                required
                                fullWidth
                                id="lastName"
                                label="Last Name"
                                name="lastName"
                                autoComplete="lname"
                            />
                        </Grid>
                        <Grid item xs={12}>
                            <TextField
                                variant="outlined"
                                required
                                fullWidth
                                id="email"
                                label="Email Address"
                                name="email"
                                autoComplete="email"
                            />
                        </Grid>
                        <Grid item xs={12}>
                            <TextField
                                variant="outlined"
                                required
                                fullWidth
                                name="password"
                                label="Password"
                                type="password"
                                id="password"
                                autoComplete="current-password"
                            />
                        </Grid>
                        <Grid item xs={12}>
                            <FormControlLabel
                                control={<Checkbox value="allowExtraEmails" color="primary" />}
                                label="I want to receive inspiration, marketing promotions and updates via email."
                            />
                        </Grid>
                    </Grid>
                    <Button
                        type="submit"
                        fullWidth
                        variant="contained"
                        color="primary"
                        className={classes.submit}
                    >
                        Sign Up
          </Button>
                    <Grid container justify="flex-end">
                        <Grid item>
                            <Link href="#" variant="body2">
                                Already have an account? Sign in
              </Link>
                        </Grid>
                    </Grid>
                </form>
            </div>
            <Box mt={5}>
                <Copyright />
            </Box>
        </Container>
    );
}

应用程序.js

import React from 'react';
import Container from '@material-ui/core/Container';
import Typography from '@material-ui/core/Typography';
import SignUp from './sign-up/SignUp.js';
import SignIn from './sign-in/SignIn.js';
import Box from '@material-ui/core/Box';
import Link from '@material-ui/core/Link';
import { Button, Paper } from '@material-ui/core';

export default function App() {
    return (    
        <div>
            <Container maxWidth="sm">
                <Box my={4}>
                    <Typography variant="h4" component="h1" gutterBottom>
                        Creating a website!
            </Typography>
                    <ProTip />
                    <button onClick={SignUp}>
                        Click me!
                    </button>
                    <SignIn />
                    <Copyright />
                </Box>
                </Container>
        </div>
    );
}

在这种情况下如何正确转换?

标签: javascriptreactjsmaterial-ui

解决方案


您正在尝试将 React 组件调用为事件处理程序:

<button onClick={SignUp}>

这是行不通的。相反,您可以例如创建一个标志,在onClick处理程序中将其设置为 true,然后SignUp基于此标志进行渲染。

const [showSignUp, setShowSignUp]= React.useState(false)
... 
<button onClick={()=>setShowSignUp(s=>!s)}>Click me!</button>
{showSignUp ? <SignUp /> : <SignIn />}

推荐阅读