简体   繁体   English

如何从自定义挂钩验证中正确显示错误消息?

[英]How to display error message correctly from custom hook validation?

I have a multi-step form.我有一个多步骤表格。 Currently, the parent component, is getting the state data through props passed down to the form components.目前,父组件正在通过传递给表单组件的 props 获取 state 数据。 The submit button is within the parent component.提交按钮位于父组件中。 This works and the steps work.这有效并且步骤有效。 However, when clicking on an input field, when it loses focus, it triggers the error message of every field within the multi-step form instead of the field that triggered the error being the only field with the error.但是,当单击输入字段时,当它失去焦点时,它会触发多步表单中每个字段的错误消息,而不是触发错误的字段是唯一出现错误的字段。 I'm using the error prop of the <TextField/> to trigger the error visuals for the user.我正在使用<TextField/>error道具来触发用户的错误视觉效果。 The fields are also validated in validateAuth.js and values are processed in useFormValidation.js .字段也在 validateAuth.js 中validateAuth.js ,值在useFormValidation.js中处理。 I'm also stuck on submitting the user sign up form data from the parent components state from one submit button within the parent component.我还坚持从父组件中的一个提交按钮提交来自父组件 state 的用户注册表单数据。

I've already tried to set errors={errors} and use if statements within useEffect hooks such as我已经尝试设置 errors={errors} 并在 useEffect 挂钩中使用 if 语句,例如

React.useEffect(() => {
  if (props.errors) {
    setErr(true)
  }
}, [err, props.errors]);

However, that's resulted in my entire page loading with errors displayed without any user input.但是,这导致我的整个页面加载时显示错误而没有任何用户输入。

Here's a code sandbox with a similarity to my exact development set up.这是一个与我的确切开发设置相似的代码沙箱。

Code is the same, just simplified with the bare essentials.代码是相同的,只是用最基本的要素进行了简化。

https://codesandbox.io/s/hooks-custom-authentication-final-8ldcw https://codesandbox.io/s/hooks-custom-authentication-final-8ldcw

Expected Results: Multi-Step Form loads, validates fields each time user tries to go to the next step by clicking Next, if there is an error, show the field that caused the error in red only and display the error text through material-ui helpertext.预期结果:多步表单加载,每次用户尝试通过单击下一步将 go 进行下一步时验证字段,如果有错误,仅以红色显示导致错误的字段,并通过 material-ui helpertext 显示错误文本。 User should not be able to go to the next step when an error occurs on a input field within that step.当该步骤中的输入字段发生错误时,用户不应该能够 go 到下一步。 When a field shows an error, the rest of the fields that were not in error, remain in their normal non-erroneous state.当某个字段显示错误时,未出错字段的 rest 将保持在其正常的非错误 state 中。 On last step, Verify button submits user data for sign up.在最后一步,验证按钮提交用户数据以进行注册。

Actual: Form is erroring all fields once any input field is clicked then the user clicks anywhere else and causes the field to lose focus.实际:一旦单击任何输入字段,然后用户单击其他任何地方并导致该字段失去焦点,表单就会对所有字段进行错误处理。 Users are able to click freely through the steps of sign up regardless of errors.无论错误如何,用户都可以通过注册步骤自由点击。

If you check your validateAuth.js , this code will check all the input as a whole.如果您检查您的validateAuth.js ,此代码将检查所有输入作为一个整体。 The first time you call this function, all input values are empty, that's why you got the error in all input.第一次调用这个 function 时,所有输入值都是空的,这就是为什么你在所有输入中都会出错。 I think this kind of code is suitable if you have all input in the same page and validate when submit button is pressed.如果您在同一页面中输入所有内容并在按下提交按钮时进行验证,我认为这种代码是合适的。 But, in your case you should change your validation to check on individual input value like this但是,在您的情况下,您应该更改验证以检查单个输入值,如下所示

export default function validateAuth(input) {
 let errors = {};
 switch (input.key) {
 case "email": {
  if (!input.value) {
    errors.email = "Required Email";
  } else if (
    !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(input.value)
  ) {
    errors.email = "Invalid email address";
  }
  return errors;
 }
 case "password": {
  if (!input.value) {
    errors.password = "Required Password";
  } else if (input.value.length < 6) {
    errors.password = "Password must be at least 6 characters";
  }
  return errors;
 }
 case "username": {
  if (!input.value) {
    errors.username = "Required Username";
  } else if (input.value.length < 6) {
    errors.username = "Username must be 6-12 characters";
  }
  return errors;
 }
 case "verify": {
  if (!input.value) {
    errors.verify = "Required Verification";
  } else if (input.value.length < 1) {
    errors.verify = "Please input the 4 digit code.";
  }
  return errors;
 }
 default:
   return errors;
 }
}

Then, you should also change your handleBlur function to send only a single input value然后,您还应该更改您的handleBlur function 以仅发送单个输入值

function handleBlur(e) {
 const { name, value } = e.target;
 const input = {
  key: name,
  value
 };
 const validationErrors = validate(input);
 setErrors({
  ...errors,
  ...validationErrors
 });
}

Then, you should add a check on error object to enable/disable your next button然后,您应该添加对错误 object 的检查以启用/禁用您的下一个按钮

编辑 Hooks 自定义身份验证 Final

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM