首页 > 解决方案 > 如何在反应中添加输入验证?

问题描述

我有一个简单的表格,它有firstNamelastName

    <label htmlFor="firstName">First Name: </label>
    <input
      type="text"
      className="form-control"
      id="firstName"
      name="firstName"
      value={basicDetails.firstName}
      onChange={(event) => handleInputChange(event)}
    />

    <label htmlFor="lastName">Last Name: </label>
    <input
      type="text"
      className="form-control"
      id="lastName"
      name="lastName"
      value={basicDetails.lastName}
      onChange={(event) => handleInputChange(event)}
    />

为此,我正在尝试添加验证。

验证规则是,

我试图实现这一目标的事情,

组件/utils.js

export function isLettersOnly(string) {
  return /^[a-zA-Z]+$/.test(string);
}

组件/basic_details.js

  const handleInputChange = (event) => {
    const { name, value } = event.target;

    if (!isLettersOnly(value)) {
      return;
    }

    setValue((prev) => {
      const basicDetails = { ...prev.basicDetails, [name]: value };
      return { ...prev, basicDetails };
    });
  };

在句柄输入字段上,我正在进行验证以检查输入是否具有值,但我无法理解如何捕捉实际验证错误并显示在相应的输入框下方。

请帮我在各个字段上显示验证消息。

工作示例:

编辑下一个动态测试问题(分叉)

标签: javascripthtmlreactjsformsvalidation

解决方案


我建议errors在表单数据中添加一个属性form_context

const [formValue, setFormValue] = useState({
  basicDetails: {
    firstName: '',
    lastName: '',
    profileSummary: '',
    errors: {},
  },
  ...
});

将验证添加到basic_details子表单:

const ErrorText = ({ children }) => (
  <div style={{ color: 'red' }}>{children}</div>
);

const BasicDetails = () => {
  const [value, setValue] = React.useContext(FormContext);
  const { basicDetails } = value;

  const handleInputChange = (event) => {
    const { name, value } = event.target;

    if (!isLettersOnly(value)) {
      setValue((value) => ({
        ...value,
        basicDetails: {
          ...value.basicDetails,
          errors: {
            ...value.basicDetails.errors,
            [name]: 'Can have only letters.',
          },
        },
      }));
      return;
    }

    switch (name) {
      case 'firstName': {
        const error = value.length < 4 ? 'Length must be at least 4.' : null;
        setValue((value) => ({
          ...value,
          basicDetails: {
            ...value.basicDetails,
            errors: {
              ...value.basicDetails.errors,
              [name]: error,
            },
          },
        }));
        break;
      }

      case 'lastName': {
        const error = value.length < 3 ? 'Length must be at least 3.' : null;
        setValue((value) => ({
          ...value,
          basicDetails: {
            ...value.basicDetails,
            errors: {
              ...value.basicDetails.errors,
              [name]: error,
            },
          },
        }));
        break;
      }

      default:
      // ignore
    }

    setValue((prev) => {
      const basicDetails = { ...prev.basicDetails, [name]: value };
      return { ...prev, basicDetails };
    });
  };

  return (
    <>
      <br />
      <br />
      <div className="form-group col-sm-6">
        <label htmlFor="firstName">First Name: </label>
        <input
          type="text"
          className="form-control"
          id="firstName"
          name="firstName"
          value={basicDetails.firstName}
          onChange={(event) => handleInputChange(event)}
        />
      </div>
      <br />
      {basicDetails.errors.firstName && (
        <ErrorText>{basicDetails.errors.firstName}</ErrorText>
      )}
      <br />
      <br />
      <div className="form-group col-sm-4">
        <label htmlFor="lastName">Last Name: </label>
        <input
          type="text"
          className="form-control"
          id="lastName"
          name="lastName"
          value={basicDetails.lastName}
          onChange={(event) => handleInputChange(event)}
        />
      </div>
      <br />
      {basicDetails.errors.lastName && (
        <ErrorText>{basicDetails.errors.lastName}</ErrorText>
      )}
      <br />
    </>
  );
};

最后,检查字段值和错误以disabled在 中的下一个按钮上设置属性index.js。第一个!(value.basicDetails.firstName && value.basicDetails.lastName)条件处理初始/空值状态,而第二个条件处理错误值。

{currentPage === 1 && (
  <>
    <BasicDetails />
    <button
      disabled={
        !(
          value.basicDetails.firstName && value.basicDetails.lastName
        ) ||
        Object.values(value.basicDetails.errors).filter(Boolean).length
      }
      onClick={next}
    >
      Next
    </button>
  </>
)}

可以为以下步骤重复此模式。

编辑 how-to-add-input-validation-in-react


推荐阅读