【问题标题】:Form validation React function component with useState表单验证 React 函数组件与 useState
【发布时间】:2021-12-03 12:34:21
【问题描述】:

我正在使用组件函数和 useState 使用 React 处理客户端验证表单。问题是当我单击提交时,handleSubmit 会更新带有错误的“验证”状态,但是当状态更改时它们不会呈现。仅当我在输入字段上输入一些值时才会呈现它们。我该如何解决这个问题?

您可以在下面找到代码:

import React, { useState } from 'react';

function RegistrationView() {
  const [inputValues, setInputValue] = useState({
    fName: '',
    lName: '',
    email: '',
    password: '',
    confirmPassword: '',
  });

  const [validation, setValidation] = useState({
    fName: '',
    lName: '',
    email: '',
    password: '',
    confirmPassword: '',
  });

  //handle submit updates
  function handleChange(event) {
    const { name, value } = event.target;
    setInputValue({ ...inputValues, [name]: value });
  }

  const handleSubmit = (e) => {
    e.preventDefault();
    let errors = validation;

    //first Name validation
    if (!inputValues.fName.trim()) {
      errors.fName = 'First name is required';
    } else {
      errors.fName = '';
    }
    //last Name validation
    if (!inputValues.lName.trim()) {
      errors.lName = 'Last name is required';
    } else {
      errors.lName = '';
    }

    // email validation
    const emailCond =
      "/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$/";
    if (!inputValues.email.trim()) {
      errors.email = 'Email is required';
    } else if (!inputValues.email.match(emailCond)) {
      errors.email = 'Please ingress a valid email address';
    } else {
      errors.email = '';
    }

    //password validation
    const cond1 = '/^(?=.*[a-z]).{6,20}$/';
    const cond2 = '/^(?=.*[A-Z]).{6,20}$/';
    const cond3 = '/^(?=.*[0-9]).{6,20}$/';
    const password = inputValues.password;
    if (!password) {
      errors.password = 'password is required';
    } else if (password.length < 6) {
      errors.password = 'Password must be longer than 6 characters';
    } else if (password.length >= 20) {
      errors.password = 'Password must shorter than 20 characters';
    } else if (!password.match(cond1)) {
      errors.password = 'Password must contain at least one lowercase';
    } else if (!password.match(cond2)) {
      errors.password = 'Password must contain at least one capital letter';
    } else if (!password.match(cond3)) {
      errors.password = 'Password must contain at least a number';
    } else {
      errors.password = '';
    }

    //matchPassword validation
    if (!inputValues.confirmPassword) {
      errors.confirmPassword = 'Password confirmation is required';
    } else if (inputValues.confirmPassword !== inputValues.Password) {
      errors.confirmPassword = 'Password does not match confirmation password';
    } else {
      errors.password = '';
    }

    return setValidation(errors);
  };

  return (
    <div>
      <div className='sign-up-form'>
        <form
          id='registrationForm'
          action='/'
          method='POST'
          onSubmit={handleSubmit}
        >
          <div className='form-control'>
            <input
              placeholder='First Name'
              type='string'
              name='fName'
              id='fName'
              className='input-field'
              onChange={(e) => handleChange(e)}
              value={inputValues.fName}
            />
            {validation.fName && <p>{validation.fName}</p>}
            {validation.fName && console.log(validation)}
          </div>
          <div className='form-control'>
            <input
              placeholder='Last Name'
              type='string'
              id='lName'
              name='lName'
              className='input-field'
              onChange={(e) => handleChange(e)}
              value={inputValues.lName}
            />
            {validation.lName && <p>{validation.lName}</p>}
          </div>
          <div className='form-control'>
            <input
              placeholder='email'
              type='email'
              name='email'
              className='input-field'
              onChange={(e) => handleChange(e)}
              value={inputValues.email}
            />
          </div>
          {validation.email && <p>{validation.email}</p>}

          <div className='form-control'>
            <input
              placeholder='password'
              type='password'
              name='password'
              className='input-field'
              onChange={(e) => handleChange(e)}
              value={inputValues.password}
              required
            />
            {validation.password && <p>{validation.password}</p>}
          </div>
          <div className='form-control'>
            <input
              placeholder='confirm password'
              type='password'
              name='confirmPassword'
              className='input-field'
              onChange={(e) => handleChange(e)}
              value={inputValues.confirmPassword}
              required
            />
          </div>
          <button type='submit' id='submit-button'>
            submit
          </button>
          <span className='form-input-login'>
            Already have an account? Login <a href='#'>here</a>
          </span>
        </form>
      </div>
    </div>
  );
}

export default RegistrationView;

谢谢

【问题讨论】:

  • 我是否正确理解您想要在用户输入时而不是在提交后进行验证?如果是,则将if语句和setValidation从handleSubmit放到handleChange中。

标签: reactjs use-state


【解决方案1】:

您可以将验证逻辑放在一个单独的函数中,并在 textInput 更改时使用 useEffect 挂钩调用它。我希望这有帮助。您可以通过任何方式进一步改进验证逻辑。

import React, { useEffect, useState } from "react";

function RegistrationView() {
  const [inputValues, setInputValue] = useState({
    fName: "",
    lName: "",
    email: "",
    password: "",
    confirmPassword: "",
  });

  const [validation, setValidation] = useState({
    fName: "",
    lName: "",
    email: "",
    password: "",
    confirmPassword: "",
  });

  //handle submit updates
  function handleChange(event) {
    const { name, value } = event.target;
    setInputValue({ ...inputValues, [name]: value });
  }

  const checkValidation = () => {
    let errors = validation;

    //first Name validation
    if (!inputValues.fName.trim()) {
      errors.fName = "First name is required";
    } else {
      errors.fName = "";
    }
    //last Name validation
    if (!inputValues.lName.trim()) {
      errors.lName = "Last name is required";
    } else {
      errors.lName = "";
    }

    // email validation
    const emailCond =
      "/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$/";
    if (!inputValues.email.trim()) {
      errors.email = "Email is required";
    } else if (!inputValues.email.match(emailCond)) {
      errors.email = "Please ingress a valid email address";
    } else {
      errors.email = "";
    }

    //password validation
    const cond1 = "/^(?=.*[a-z]).{6,20}$/";
    const cond2 = "/^(?=.*[A-Z]).{6,20}$/";
    const cond3 = "/^(?=.*[0-9]).{6,20}$/";
    const password = inputValues.password;
    if (!password) {
      errors.password = "password is required";
    } else if (password.length < 6) {
      errors.password = "Password must be longer than 6 characters";
    } else if (password.length >= 20) {
      errors.password = "Password must shorter than 20 characters";
    } else if (!password.match(cond1)) {
      errors.password = "Password must contain at least one lowercase";
    } else if (!password.match(cond2)) {
      errors.password = "Password must contain at least one capital letter";
    } else if (!password.match(cond3)) {
      errors.password = "Password must contain at least a number";
    } else {
      errors.password = "";
    }

    //matchPassword validation
    if (!inputValues.confirmPassword) {
      errors.confirmPassword = "Password confirmation is required";
    } else if (inputValues.confirmPassword !== inputValues.Password) {
      errors.confirmPassword = "Password does not match confirmation password";
    } else {
      errors.password = "";
    }

    setValidation(errors);
  };

  useEffect(() => {
    checkValidation();
  }, [inputValues]);

  const handleSubmit = (e) => {
    e.preventDefault();
  };

  return (
    <div>
      <div className="sign-up-form">
        <form
          id="registrationForm"
          action="/"
          method="POST"
          onSubmit={handleSubmit}
        >
          <div className="form-control">
            <input
              placeholder="First Name"
              type="string"
              name="fName"
              id="fName"
              className="input-field"
              onChange={(e) => handleChange(e)}
              value={inputValues.fName}
            />
            {validation.fName && <p>{validation.fName}</p>}
            {validation.fName && console.log(validation)}
          </div>
          <div className="form-control">
            <input
              placeholder="Last Name"
              type="string"
              id="lName"
              name="lName"
              className="input-field"
              onChange={(e) => handleChange(e)}
              value={inputValues.lName}
            />
            {validation.lName && <p>{validation.lName}</p>}
          </div>
          <div className="form-control">
            <input
              placeholder="email"
              type="email"
              name="email"
              className="input-field"
              onChange={(e) => handleChange(e)}
              value={inputValues.email}
            />
          </div>
          {validation.email && <p>{validation.email}</p>}

          <div className="form-control">
            <input
              placeholder="password"
              type="password"
              name="password"
              className="input-field"
              onChange={(e) => handleChange(e)}
              value={inputValues.password}
              required
            />
            {validation.password && <p>{validation.password}</p>}
          </div>
          <div className="form-control">
            <input
              placeholder="confirm password"
              type="password"
              name="confirmPassword"
              className="input-field"
              onChange={(e) => handleChange(e)}
              value={inputValues.confirmPassword}
              required
            />
          </div>
          <button type="submit" id="submit-button">
            submit
          </button>
          <span className="form-input-login">
            Already have an account? Login <a href="#">here</a>
          </span>
        </form>
      </div>
    </div>
  );
}

export default RegistrationView;

【讨论】:

  • 谢谢,我去看看!
【解决方案2】:

作为代码上的标记,错误设置验证基于引用调用,因此在设置状态后不呈现组件。请尝试深度克隆您的错误,如下所示。

 let errors = JSON.parse(JSON.stringify(validation));

我希望它对你有用。谢谢

【讨论】:

  • 谢谢!它有效!
【解决方案3】:

您可以尝试使用单独的运算符进行克隆。

let errors = {...validation}

或者你可以使用 react-hook-form 库。它易于使用且非常独立。

react hook form

【讨论】:

  • 太棒了!有用!谢谢你!我能问你为什么会这样吗??
  • 在javascript中,对象和函数都是非原始类型。这意味着,如果您将对象分配给另一个变量,则在内存中两个变量都指向同一个变量。使用 Seperate operator(...) 您可以克隆对象的内容而不是引用。你可以看看这篇文章:edureka.co/blog/data-types-in-javascript
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-04
  • 1970-01-01
  • 2021-10-11
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多