1

I need some help, I am new to react. I created a Functional Component form with Context API and I am trying to prevent it from submitting if the form failed validation and return false. I have check the validation and it is working by uncommenting the html input button and comment out the React Link (<Link></Link>) button. I try the code with class component and bind the handleChange and handleSubmit inside the constructor and it work: however, I do not want to used the class component. I just want to used the function component.

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>
  );
};

1
  • Can you share a CodeSandbox that reproduces the issue? Commented Apr 25, 2021 at 22:04

1 Answer 1

1

Issue

The issue isn't that the form is being submitted upon validation (true or false), but rather that both field validation and route navigation are more or less occurring at the same time. The Link, upon being clicked, will immediately navigate to the specified path.

Solution

Seems you want to validate the input, and only upon successful validation, call the reSetEmployee function on the context and navigate to "/addressForm".

I suggest rendering the submit button not within a Link and use imperative navigation. For this I'm assuming you are using react-router-dom library.

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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.