Для вступления в силу необходимо дважды подать props.history.pu sh - PullRequest
0 голосов
/ 13 марта 2020

В настоящее время я возлюсь с проверкой формы на стороне клиента. Там нет никакого конца или что-то в этом роде. У меня есть функция отправки, и я пытаюсь отправить пользователя sh на домашнюю страницу после отправки действительной формы с использованием props.history.pu sh. По какой-то причине я должен дважды отправить форму для функции отправки, чтобы фактически вывести пользователя на домашнюю страницу. Я не уверен, почему это происходит. Ниже я собираюсь предоставить свой хук useForm, мою страницу входа в систему и мою функцию проверки, которую я использую. Я чувствую, что ответ может быть очевидным, но я просто не могу найти проблему.

useForm Hook:

import { useState } from "react"

const INITIAL_STATE = {
  email: "",
  password: ""
}

const UseForm = (ValidateLogin, props) => {
  const [formData, setFormData] = useState(INITIAL_STATE)
  const [errors, setErrors] = useState({})
  const [user, setUser] = useState(null)

  const handleChange = field => e => {
    setFormData({ ...formData, [field]: e.target.value })
  }

  const handleSubmit = event => {
    event.preventDefault()
    setUser(formData)
    setErrors(ValidateLogin(formData))
    user && !errors.email && !errors.password && props.history.push("/")
  }
  return {
    handleChange,
    handleSubmit,
    formData,
    user,
    errors
  }
}

export default UseForm

Страница входа в систему:

import React from "react"
import UseForm from "../Login/UseForm"
import ValidateLogin from "../Login/ValidateLogin"
import { makeStyles } from "@material-ui/core/styles"

// Material UI
import TextField from "@material-ui/core/TextField"
import Button from "@material-ui/core/Button"
import Typography from "@material-ui/core/Typography"
import Container from "@material-ui/core/Container"

const useStyles = makeStyles(theme => ({
  form: {
    textAlign: "center",
    width: "100%", // Fix IE 11 issue.
    marginTop: theme.spacing(1),
    position: "relative"
  },
  logo: {
    width: 80,
    margin: "20px auto 20px auto"
  },
  paper: {
    marginTop: theme.spacing(8),
    display: "flex",
    flexDirection: "column",
    alignItems: "center"
  },
  submit: {
    margin: theme.spacing(3, 0, 2),
    position: "relative"
  },
  progress: {
    position: "absolute"
  },
  customError: {
    color: "red",
    fontSize: "0.8rem",
    width: "100%",
    position: "absolute"
  }
}))

const Login = props => {
  const classes = useStyles()

  const { handleChange, handleSubmit, formData, user, errors } = UseForm(
    ValidateLogin,
    props
  )

  const isInvalid = !formData.email || !formData.password

  return (
    <div style={{ textAlign: "center" }}>
      <Typography variant='h5' gutterBottom>
        Welcome, Please Login
      </Typography>
      <Container component='main' maxWidth='xs'>
        <form className={classes.form} onSubmit={handleSubmit}>
          <TextField
            variant='outlined'
            fullWidth
            margin='normal'
            label='Email'
            type='text'
            name='email'
            value={formData.email}
            error={errors.email ? true : false}
            helperText={errors.email}
            onChange={handleChange("email")}
          />
          <TextField
            variant='outlined'
            margin='normal'
            fullWidth
            label='Password'
            type='password'
            name='password'
            value={formData.password}
            error={errors.password ? true : false}
            helperText={errors.password}
            onChange={handleChange("password")}
          />
          <br />
          <Button
            variant='outlined'
            color='primary'
            type='submit'
            disabled={isInvalid}
            className={classes.submit}
          >
            Submit
          </Button>
        </form>
      </Container>
      <br />
      {user &&
        !errors.email &&
        !errors.password &&
        JSON.stringify(user, null, 2)}
    </div>
  )
}

export default Login

Подтверждение входа в систему:

export default function ValidateLogin(formData) {
  let errors = {}

  if (!formData.email) {
    errors.email = "Email address is required"
  } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
    errors.email = "Email address is invalid"
  }
  if (!formData.password) {
    errors.password = "Password is required"
  } else if (formData.password.length < 6) {
    errors.password = "Password must be longer than 6 characters"
  }

  return errors
}

Любые полезные предложения или отзывы будут очень полезны оценили !! Я прошу прощения за многословный вопрос. Спасибо, что нашли время, чтобы прочитать это.

1 Ответ

1 голос
/ 13 марта 2020

Похоже, что ваша проблема является условной в этом блоке:

setUser(formData)
setErrors(ValidateLogin(formData))
user && !errors.email && !errors.password && props.history.push("/")

user и errors не будут обновлены к тому времени, когда это условие будет оценено, поскольку установщики состояний являются асинхронными c , Вот более подробное объяснение .

Вот почему он работает на втором представлении. Затем значения были обновлены, и условие прошло.

Возможно, это не желаемое конечное решение, но оно должно решить проблему для вас.

const handleSubmit = event => {
  event.preventDefault()
  setUser(formData)

  // Use temp variable so that you can use it immediately below
  const tempErrors = ValidateLogin(formData);
  setErrors(tempErrors)

  // Use the formData directly and the tempErrors
  formData && !tempErrors.email && !tempErrors.password && props.history.push("/")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...