【问题标题】:React Functional Component: How to prevent form from submitting if validation failedReact 功能组件:如果验证失败,如何防止表单提交
【发布时间】:2025-12-27 16:40:11
【问题描述】:

我需要一些帮助,我是新来的反应。我使用 Context API 创建了一个功能组件表单,如果表单验证失败并返回 false,我试图阻止它提交。我已经检查了验证,它通过取消注释 html 输入按钮并注释掉 React Link (<Link></Link>) 按钮来工作。我尝试使用类组件的代码并 在构造函数中绑定 handleChangehandleSubmit 并且它可以工作:但是,我不想使用类组件。我只想用函数组件。

const Employee = () => {
  const ctx = useContext(FormActualContext);

  const handleChange = (event) => {
    ctx.handleChange({
      event,
      type: 'employee',
    });
  };

  const validate = () => {
    const {
      firstName,
      lastName,
      email,
      dateOfBirth,
      phoneNum,
    } = ctx.formData.employee;
    const { employee } = ctx.formErrors;
    let {
      firstNameError,
      lastNameError,
      emailError,
      dateOfBirthError,
      phoneNumError,
    } = employee;

    firstNameError = !firstName ? 'First name can not be blank' : '';
    lastNameError = lastName === '' ? 'Last name can not be blank' : '';
    dateOfBirthError = !dateOfBirth ? 'Enter a valid date of birth' : '';
    if (!validateEmail(email)) {
      emailError =
        email === '' ? 'Enter a valid email' : `${email} is not valid email`;
    } else {
      emailError = '';
    }
    if (!validatePhoneNumber(phoneNum)) {
      phoneNumError =
        phoneNum === ''
          ? 'Enter a valid phone'
          : `${phoneNum} is not a valid phone number`;
    } else {
      phoneNumError = '';
    }

    if (
      firstNameError ||
      lastNameError ||
      emailError ||
      dateOfBirthError ||
      phoneNumError
    ) {
      ctx.setFormErrors({
        employee: {
          ...employee,
          firstNameError,
          lastNameError,
          emailError,
          dateOfBirthError,
          phoneNumError,
        },
      });
      return false;
    }
    return true;
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    const isValid = validate();
    if (isValid) {
      ctx.reSetEmployee();
    }
  };
  const {
    employee: {
      firstNameError,
      lastNameError,
      emailError,
      dateOfBirthError,
      phoneNumError,
    },
  } = ctx.formErrors;
  return (
    <div className="container_fluid">
      <div className="registration_form_container">
        <div className="register_context">
          <form action="" onSubmit={handleSubmit} className="registration_form">
            <div className="form-group">
              <input
                type="text"
                name="firstName"
                id="firstName"
                placeholder={'Enter first name'}
                onChange={handleChange}
              />
              <span>{firstNameError}</span>
            </div>
            <div className="form-group">
              <input
                type="text"
                name="lastName"
                id="lastName"
                placeholder={'Enter last name'}
                onChange={handleChange}
              />
              <span>{lastNameError}</span>
            </div>
            <div className="form-group">
              <input
                type="text"
                name="email"
                id="email"
                placeholder={'Enter email address'}
                onChange={handleChange}
              />
              <span>{emailError}</span>
            </div>
            <div className="form-group">
              <input
                type="date"
                name="dateOfBirth"
                id="dateOfBirth"
                placeholder={'Enter date of birth'}
                onChange={handleChange}
              />
              <span>{dateOfBirthError}</span>
            </div>
            <div className="form-group">
              <input
                type="text"
                name="phoneNum"
                id="phoneNum"
                placeholder={'Enter phone number (international: +1)'}
                onChange={handleChange}
              />
              <span>{phoneNumError}</span>
            </div>
            <div className="form-group custom_btn_container">
              {/*<input type="submit" className="btn" value="Register"/>*/}
              <Link to="/addressForm">
                <input type="submit" className="btn" value="Register" />
              </Link>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
};

【问题讨论】:

标签: reactjs


【解决方案1】:

问题

问题不在于表单在验证时提交(真或假),而是字段验证路由导航或多或少同时发生。 Link,点击后会立即导航到指定路径。

解决方案

您似乎想验证输入,只有在验证成功后,调用上下文中的reSetEmployee 函数并导航到“/addressForm”。

我建议在Link 中呈现提交按钮,并使用命令式导航。为此,我假设您使用的是 react-router-dom 库。

import { useHistory } from 'react-router-dom';

...

const history = useHistory();

...

const handleSubmit = (event) => {
  event.preventDefault();
  const isValid = validate();
  if (isValid) {
    ctx.reSetEmployee();
    history.push("/addressForm");
  }
};

...

<div className="form-group custom_btn_container">
  <input type="submit" className="btn" value="Register"/>
</div>

【讨论】: