Второй аргумент в функции reactjs не определен

#javascript #reactjs #firebase #material-ui

#javascript #reactjs #firebase #материал-пользовательский интерфейс

Вопрос:

Я работал над небольшим проектом, чтобы ознакомиться с ReactJS, и пока мне очень весело. У меня было несколько проблем, которые были решены с помощью here до сих пор.

В настоящее время я работаю над изменением ссылок в моем заголовке на основе роли авторизованного пользователя. Кажется, что эта часть работает нормально, пока я не попытаюсь зарегистрировать пользователя. Я получаю проблему, из-за которой props.firebase строка кода не определена. Есть идеи о том, что мне нужно сделать, чтобы сделать это не неопределенным? Когда я удаляю аргумент {AuthUser}, кажется, что все идет нормально, но при добавлении его в функцию возникают проблемы. Код для файла регистрации приведен ниже:

 import {Link as RouterLink, withRouter} from 'react-router-dom'
import {compose} from 'recompose';
import {withFirebase} from '../../components/Firebase'

import * as ROUTES from '../../constants/routes'

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 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';
import SignInPage, {SignInLink} from "../SignInPage";
import styles from '../../assets/jss/website-template/views/signUpPage';
import Header from '../../components/Header/Header';
import HeaderLinks from '../../components/Header/HeaderLinks';
import image from '../../assets/img/kissing.JPG';
import Paper from '@material-ui/core/Paper';
import AuthUserContext from '../../components/Session/context';
function Copyright() {
    return (
        <Typography variant="body2" color="textSecondary" align="center">
            {'Copyright © '}
            <Link color="inherit" href="https://material-ui.com/">
                Your Website
            </Link>{' '}
            {new Date().getFullYear()}
            {'.'}
        </Typography>
    );
}

const useStyles = makeStyles(styles);


const SignUpPage = () => (
    <div>
        <AuthUserContext.Consumer>
            {authUser => authUser === null ?
                <SignUpForm authUser={null} /> :
                <SignUpForm authUser={authUser} /> }
        </AuthUserContext.Consumer>
    </div>
);

const SignUpFormBase = ({authUser}, props) => {
    const classes = useStyles();
    const [username, setUsername] = useState('');
    const [email, setEmail] = useState('');
    const [passwordOne, setPasswordOne] = useState('');
    const [passwordTwo, setPasswordTwo] = useState('');
    const [inviteCode, setInviteCode] = useState('');
    const [error, setError] = useState(null);
    const {...rest} = props;

    const isInvalid =
        passwordOne !== passwordTwo ||
        passwordOne === '' ||
        email === '' ||
        username === '';

    const doSubmit = event => {

        props.firebase
            .checkInviteCode(inviteCode)
            .then(role => {
                props.firebase
                    .doCreateUserWithEmailAndPassword(email, passwordOne)
                    .then(authUser => {
                        return props.firebase
                            .user(authUser.user.uid)
                            .set({
                                username,
                                email,
                                role,
                            });
                    })
                    .then(authUser => {
                        setUsername(username);
                        setPasswordOne(passwordOne);
                        setPasswordTwo(passwordTwo);
                        setEmail(email);
                        setInviteCode(inviteCode);
                        props.history.push(ROUTES.HOME);
                    })
                    .catch(error => {
                        setError(error);
                    });
            })
            .catch(error => {
                console.log(error);
            });

        event.preventDefault();
    }

    return (
        <div>
            <Header
                absolute
                color="transparent"
                brand="Material Kit React"
                rightLinks={<HeaderLinks authUser={authUser}/>}
                {...rest}
            />
            <div
                className={classes.pageHeader}
                style={{
                    backgroundImage: "url("   image   ")",
                    backgroundSize: "cover",
                    backgroundPosition: "top center"
                }}
            >
                <Grid component="main" className={classes.container}>
                    <CssBaseline/>
                    <Grid item component={Paper} xs={12} sm={12} md={4}>
                        <div className={classes.paper}>
                            <Avatar className={classes.avatar}>
                                <LockOutlinedIcon/>
                            </Avatar>
                            <Typography component="h1" variant="h5">
                                Sign up
                            </Typography>
                            <form className={classes.form} noValidate onSubmit={doSubmit}>
                                <TextField
                                    margin="normal"
                                    autoComplete="fname"
                                    name="username"
                                    variant="outlined"
                                    required
                                    fullWidth
                                    id="username"
                                    label="Username"
                                    autoFocus
                                    value={username}
                                    onChange={event => setUsername(event.target.value)}
                                />
                                <TextField
                                    margin="normal"
                                    variant="outlined"
                                    required
                                    fullWidth
                                    id="email"
                                    label="Email Address"
                                    name="email"
                                    autoComplete="email"
                                    value={email}
                                    onChange={event => setEmail(event.target.value)}
                                />
                                <TextField
                                    margin="normal"
                                    variant="outlined"
                                    required
                                    fullWidth
                                    name="password"
                                    label="Password"
                                    type="password"
                                    id="password"
                                    autoComplete="current-password"
                                    value={passwordOne}
                                    onChange={event => setPasswordOne(event.target.value)}
                                />
                                <TextField
                                    margin="normal"
                                    variant="outlined"
                                    required
                                    fullWidth
                                    name="password"
                                    label="Confirm Password"
                                    type="password"
                                    id="password"
                                    autoComplete="confirm-password"
                                    value={passwordTwo}
                                    onChange={event => setPasswordTwo(event.target.value)}
                                />
                                <TextField
                                    margin="normal"
                                    variant="outlined"
                                    required
                                    fullWidth
                                    name="inviteCode"
                                    label="InviteCode"
                                    id="inviteCode"
                                    autoComplete="inviteCode"
                                    value={inviteCode}
                                    onChange={event => setInviteCode(event.target.value)}
                                />
                                <Button
                                    type="submit"
                                    fullWidth
                                    variant="contained"
                                    className={classes.submit}
                                    disabled={isInvalid}
                                >
                                    Sign Up
                                </Button>
                                {error amp;amp; <p>{error.message}</p>}
                                <Grid container>
                                    <Grid item>
                                        <SignInLink href="#" variant="body2"/>
                                    </Grid>
                                </Grid>
                                <Box mt={2}>
                                    <Copyright/>
                                </Box>
                            </form>
                        </div>
                    </Grid>
                </Grid>
            </div>
        </div>
    );
}

const SignUpLink = () => (
    <p>
        <RouterLink to={ROUTES.SIGN_UP}>Don't have an account? Sign Up</RouterLink>
    </p>
);

const SignUpForm = compose(
    withFirebase,
    withRouter,
)(SignUpFormBase);

export default SignUpPage;

export {SignUpForm, SignUpLink};
  

Как я уже упоминал, проблема заключается в том, что props.firebase значение не определено, поэтому он не может найти checkInviteCodes() функцию.

Комментарии:

1. Обычно функция react имеет один аргумент:- props? Почему ваш реквизит во втором аргументе здесь?

2. Я не думаю, что const SignUpFormBase = ({authUser}, props) работает так, как вы ожидаете; если вам нужно больше реквизита, чем просто authUser , вам нужно использовать const SignUpFormBase = (props) и props.authUser внутри.

3. @Prateek Thapa, Props — это мой второй аргумент, потому что {AuthUser} был неопределенным, если он был указан в качестве второго аргумента, вероятно, по той же причине, по которой props не определен в качестве второго аргумента. Проблема в том, что если у меня просто есть реквизиты, как мне получить AuthUser, который я передаю в SignUpFormBase из AuthUserContext. Потребительская часть? Если я оставлю все как есть и удалю {AuthUser} из базы данных формы регистрации, будет ли AuthUser доступен в реквизитах?

4. @ChrisG, спасибо. Основываясь на ответе, который был дан ниже, это на самом деле то, что я сделал. Я не понимал, что при передаче AuthUser в SignUpForm он будет доступен только через аргумент props. Спасибо!

5. Да, это и есть реквизит 🙂 И когда вы пишете параметры функции, которая будет вызвана фреймворком, единственное, что имеет значение, — это порядок, а не то, как вы их называете.

Ответ №1:

Реквизит всегда является первым аргументом, и надлежащая подпись компонента, основанного на функциях, является Component(props)

Измените этот:

 const SignUpFormBase = ({authUser}, props) => {
...
  

Для:

 const SignUpFormBase = ({authUser, firebase}) => {
...
  

Или

 const SignUpFormBase = (props) => {
...
  

и ссылаться на authUser и firebase как props.authUser и props.firebase


Ваше предыдущее решение, которое const SignUpFormBase = ({authUser}, props) => { разрушает props и присваивает его authUser локальной переменной с тем же именем. Второй (и все последующие) аргумент просто undefined .

Комментарии:

1. Ах, так что, если я передам AuthUser в базу данных SignUpFormBase, как я с <SignUpForm authUser={authUser} /> , тогда AuthUser доступен в аргументе props? Это здорово, не понял, что именно так это работает. Спасибо за ответ!

2. @NightmareRegalia Да, это базовая функция React. Я предлагаю вам ознакомиться с официальным руководством, это избавит вас от многих проблем reactjs.org/tutorial/tutorial.html