#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