Недействительные вызовы при проверке через ReactJS - PullRequest
1 голос
/ 30 мая 2020

У меня проблема с реализацией проверки входа в систему в ReactJS. Я использую Material-UI и Formik и Yap. Я реализовал его, но есть ошибка: неверный вызов ловушки. Хуки могут быть вызваны только внутри тела функционального компонента.

Пожалуйста, проверьте мой код ниже:

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { makeStyles } from '@material-ui/styles';
import { Card, CardHeader, CardContent, CardActions, Divider, Button, TextField } from '@material-ui/core';
import { useSelector, useDispatch } from 'react-redux';
import { Redirect } from 'react-router-dom';
import { login } from '../../../actions';
import AccountCircle from '@material-ui/icons/AccountCircle';
import InputAdornment from '@material-ui/core/InputAdornment';
import LockIcon from '@material-ui/icons/Lock';
import { withFormik } from 'formik';

const useStyles = makeStyles((theme) => ({
  root: {},
  cardHeader: {
    backgroundColor: theme.palette.primary.main,
    color: 'white',
    display: 'flex',
    justifyContent: 'center',
    fontSize: '2rem',
    padding: '15px',
  },
  textFieldSection: {
    padding: '40px 40px 0 40px',
  },
  loginButtonSection: {
    padding: '18px 40px 40px 40px',
  },
  loginButton: {
    width: '100%',
    height: '50px',
    textTransform: 'none',
    fontSize: '18px',
  },
}));

const LoginForm = (props) => {
  const { className, ...rest } = props;

  const isLoggedIn = useSelector((state) => state.auth.isLoggedIn);
  const referer = props.referer;
  const dispatch = useDispatch();

  const signIn = () => {
    dispatch(login(values.username, values.password));
  };

  const { classes, values, touched, errors, isSubmitting, handleChange, handleBlur, handleSubmit } = props;

  if (isLoggedIn) {
    return <Redirect to={referer} />;
  }

  return (
    <Card {...rest} className={clsx(classes.root, className)}>
      <form onSubmit={handleSubmit}>
        <CardHeader
          title="LOGIN"
          classes={{
            title: classes.cardHeader,
          }}
          className={classes.cardHeader}
        />

        <CardContent className={classes.textFieldSection}>
          <TextField
            fullWidth
            label="Username"
            name="username"
            type="text"
            variant="outlined"
            value={values.username}
            onChange={handleChange}
            onBlur={handleBlur}
            helperText={touched.username ? errors.username : ''}
            error={touched.username && Boolean(errors.username)}
            InputProps={{
              endAdornment: (
                <InputAdornment>
                  <AccountCircle />
                </InputAdornment>
              ),
            }}
          />
          <TextField
            fullWidth
            label="Password"
            name="password"
            style={{ marginTop: '1rem' }}
            type="password"
            variant="outlined"
            value={values.password}
            onChange={handleChange}
            onBlur={handleBlur}
            helperText={touched.password ? errors.password : ''}
            error={touched.password && Boolean(errors.password)}
            InputProps={{
              endAdornment: (
                <InputAdornment>
                  <LockIcon />
                </InputAdornment>
              ),
            }}
          />
        </CardContent>

        <CardActions className={classes.loginButtonSection}>
          <Button
            color="primary"
            variant="contained"
            onClick={signIn}
            className={classes.loginButton}
            disabled={isSubmitting}
          >
            Log In
          </Button>
        </CardActions>
      </form>
    </Card>
  );
};

let yup = require('yup');

const Form = withFormik({
  mapPropsToValues: ({ username, password }) => {
    return {
      username: username || '',
      password: password || '',
    };
  },

  validationSchema: yup.object().shape({
    username: yup.string().required('Required'),
    password: yup.string().min(8, 'Password must contain at least 8 characters').required('Enter your password'),
  }),

  handleSubmit: (values, { setSubmitting }) => {
    setTimeout(() => {
      // submit to the server
      alert(JSON.stringify(values, null, 2));
      setSubmitting(false);
    }, 1000);
  },
})(LoginForm);

LoginForm.propTypes = {
  className: PropTypes.string,
};

export default LoginForm(useStyles)(Form);

1 Ответ

0 голосов
/ 30 мая 2020

withFormik

Создайте класс компонента React более высокого порядка, который передает свойства и обработчики форм («FormikBag») в ваш компонент, полученный из предоставленных опций.

Просто экспортируйте Form, а не LoginForm. Также можно использовать classes do const classes = useStyles(); внутри компонента, а не передавать его в качестве реквизита.

Здесь находится рабочая копия вашего кода

Фрагмент кода

const useStyles = makeStyles(theme => ({
  root: {},
  cardHeader: {
    // backgroundColor: theme.palette.primary.main,
    backgroundColor: "blue",
    color: "white",
    display: "flex",
    justifyContent: "center",
    fontSize: "2rem",
    padding: "15px"
  },
  textFieldSection: {
    padding: "40px 40px 0 40px"
  },
  loginButtonSection: {
    padding: "18px 40px 40px 40px"
  },
  loginButton: {
    width: "100%",
    height: "50px",
    textTransform: "none",
    fontSize: "18px"
  }
}));

const LoginForm = props => {
  const { className, ...rest } = props;
  const classes = useStyles();

  const isLoggedIn = true;
  const referer = props.referer;

  const signIn = () => {
    console.log("signin");
  };

  const {
    // classes,
    values,
    touched,
    errors,
    isSubmitting,
    handleChange,
    handleBlur,
    handleSubmit
  } = props;

  if (isLoggedIn) {
    // return <Redirect to={referer} />;
    console.log("isLoggedIn", isLoggedIn);
  }

  return (
    <Card {...rest} className={clsx(classes.root, className)}>
      <form onSubmit={handleSubmit}>
        <CardHeader
          title="LOGIN"
          classes={{
            title: classes.cardHeader
          }}
          className={classes.cardHeader}
        />

        <CardContent className={classes.textFieldSection}>
          <TextField
            fullWidth
            label="Username"
            name="username"
            type="text"
            variant="outlined"
            value={values.username}
            onChange={handleChange}
            onBlur={handleBlur}
            helperText={touched.username ? errors.username : ""}
            error={touched.username && Boolean(errors.username)}
            InputProps={{
              endAdornment: (
                <InputAdornment>
                  <AccountCircle />
                </InputAdornment>
              )
            }}
          />
          <TextField
            fullWidth
            label="Password"
            name="password"
            style={{ marginTop: "1rem" }}
            type="password"
            variant="outlined"
            value={values.password}
            onChange={handleChange}
            onBlur={handleBlur}
            helperText={touched.password ? errors.password : ""}
            error={touched.password && Boolean(errors.password)}
            InputProps={{
              endAdornment: (
                <InputAdornment>
                  <LockIcon />
                </InputAdornment>
              )
            }}
          />
        </CardContent>

        <CardActions className={classes.loginButtonSection}>
          <Button
            type="submit" //<----------- see here
            color="primary"
            variant="contained"
            onClick={signIn}
            className={classes.loginButton}
            disabled={isSubmitting}
          >
            Log In
          </Button>
        </CardActions>
      </form>
    </Card>
  );
};

let yup = require("yup");

const Form = withFormik({
  mapPropsToValues: ({ username, password }) => {
    return {
      username: username || "",
      password: password || ""
    };
  },

  validationSchema: yup.object().shape({
    username: yup.string().required("Required"),
    password: yup
      .string()
      .min(8, "Password must contain at least 8 characters")
      .required("Enter your password")
  }),

  handleSubmit: (values, { setSubmitting }) => {
    setTimeout(() => {
      // submit to the server
      alert(JSON.stringify(values, null, 2));
      setSubmitting(false);
    }, 1000);
  }
})(LoginForm);

LoginForm.propTypes = {
  className: PropTypes.string
};

// export default LoginForm(useStyles)(Form);
export default Form;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...