【问题标题】:How to validate conditional form fields in React component?如何验证 React 组件中的条件表单字段?
【发布时间】:2021-07-10 23:03:21
【问题描述】:

我是 React 的新手,我试图创建一个功能性的 SignIn 表单组件,该组件基于一个可以在 Login 和 Signup 之间切换的布尔 prop 来更改其结构。 在注册版本中,有一个额外的文本字段 Confirm password 需要使用密码字段进行验证以进行匹配。 下面是组件的验证函数。

export function SignInForm({login}) {
  const [values, setValues] = useState({});
  const [error, setErrors] = useState({});

  const validate = (values) => {
    console.log(login)
    let errors = {}
    if (!values.email) {
      errors.email = "Email address is required";
    } else if (!/\S+@\S+\.\S+/.test(values.email)) {
      errors.email = "Invalid email address";
    }
    if (!values.password) {
      errors.password = "Password is required";
    } else if (values.password.length < 2) {
      errors.password = "Password should be 2 or more characters";
    }

    if (!values.confirmPass) {
      errors.confirmPass = "This field is required";
    } else if (values.confirmPass !== values.password) {
      errors.confirmPass = "Passwords do not match";
    }
    return errors;
  }
  
  const handleChange = (event) => {
    event.persist();
    setValues(values => ({ ...values, [event.target.name]: event.target.value }));
  };

  const submitChange = (event) => {
    event.preventDefault();
    setErrors(validate(values))
  }
...

以下是返回的 JSX。

<form className={classes.form} onSubmit={submitChange}>
            <TextField
              variant="outlined"
              margin="normal"
              required
              fullWidth
              id="email"
              label="Email Address"
              name="email"
              autoComplete="email"
              autoFocus
              value={values.email}
              onChange={handleChange}
              error={Boolean(error.email)}
              helperText={error.email}
            />
            <TextField
              ...
              value={values.password}
              onChange={handleChange}
              error={Boolean(error.password)}
              helperText={error.password}
            />
            {!login && 
            <TextField
              ...
              value={values.confirmPass}
              onChange={handleChange}
              error={Boolean(error.confirmPass)}
              helperText={error.confirmPass}
             
            />}

“...”属性对第一个 TextField 是通用的,表单的其余部分不显示,因为它们不是问题的一部分。

运行注册版本时(login == false),即使我在其中输入值,确认密码字段仍保持在“此字段为必填项”。它不执行验证。但其他字段验证得很好。

我在这里做错了什么?我该如何解决这个问题?任何线索将不胜感激。 谢谢。

【问题讨论】:

  • 这是因为,values.confirmPass 即使没有分配给任何元素,在状态下也是空的,如果是空的,它会给出错误

标签: javascript reactjs react-hooks material-ui


【解决方案1】:

这段代码的答案是

if(!login) {
  if (!values.confirmPass) {
    errors.confirmPass = "This field is required";
  } else if (values.confirmPass !== values.password) {
    errors.confirmPass = "Passwords do not match";
  } 
}

还有一个问题是你应该设置组件的初始状态

const [values, setValues] = useState({
    confirmPass: null,
    password: null,
    email: null,
  });
  const [error, setErrors] = useState({
    confirmPass: null,
    password: null,
    email: null,
  });

我确实有一个很好的建议给你,试着用一些东西来控制你的表单,就像 formik 和像 yup 这样的模式验证。您的代码将更加清晰和易于维护

【讨论】:

    【解决方案2】:

    你可以试试这个

    if(!login) {
      if (!values.confirmPass) {
        errors.confirmPass = "This field is required";
      } else if (values.confirmPass !== values.password) {
        errors.confirmPass = "Passwords do not match";
      } 
    }

    由于登录为假,values.confirmPass 为空。

    【讨论】:

    • 不应该是 if(!login) 吗?这样它只有在注册时才有效?
    • 没错,这就是我想说的,对不起。我已经编辑过了。谢谢!
    • 这仍然不起作用。提交时,我得到的错误是“此字段是必需的”,即使该字段已填写
    • 显然是我的错。 name 标记应与 values 属性名称相同。对于确认密码,value={values.confirmPass}name="Confirm password" 不匹配。将两者都更改为 confirmPass 有效。
    • 嗯,很高兴你能找到问题。
    猜你喜欢
    • 1970-01-01
    • 2020-06-12
    • 1970-01-01
    • 2015-06-24
    • 2017-04-15
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多