简体   繁体   中英

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. 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. The fields are also validated in validateAuth.js and values are processed in 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.

I've already tried to set errors={errors} and use if statements within useEffect hooks such as

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

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. User should not be able to go to the next step when an error occurs on a input field within that step. When a field shows an error, the rest of the fields that were not in error, remain in their normal non-erroneous 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. The first time you call this function, all input values are empty, that's why you got the error in all input. 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

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

编辑 Hooks 自定义身份验证 Final

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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