React Bootstrap Forms: <Form.Control.Feedback></Form.Control.Feedback> is not displaying when validated is false

Viewed 4840

Issue:

I'm implementing a form and having a really hard time understanding why the React Bootstrap: <Form.Control.Feedback></Form.Control.Feedback> is not displaying when validated is false

Steps To Reproduce:

  1. When the user clicks the Send Verification Code button, type={'submit'} a prop on the button and is triggered.
  2. onClick={(event) => sendVerificationCode(event)} passes the event, where I use event.preventDefault() and event.stopPropagation(); to stop cancel the event.
  3. With nothing entered in the field, the sendVerificationCode function correctly works and only logs console.log('DO NOTHING'); and console.log(validated); for testing.
  4. validated is working and is false, but why isn't the <Form.Control.Feedback></Form.Control.Feedback> not displaying.

ForgotPassword.tsx

// Page: Forgot Password
const ForgotPassword = () => {
  // React Hooks: State
  const [ email, setEmail ] = useState('');

  // React Hooks: Bootstrap
  const [ validated, setValidated ] = useState(false);

  // React Hooks: Refs
  const formRef: React.RefObject<HTMLFormElement> = useRef(null);

  // React Hooks: Redux
  const authError = useSelector((state: ReduxState) => state.authReducer.error);
  const dispatch = useDispatch();

  // React Hooks: React Router DOM
  let history = useHistory();

  // Send Verification Code
  const sendVerificationCode = (event: any) => {
    console.log('Component: sendVerificationCode working')

    // Event: Cancels Event (Stops HTML Default Form Submit)
    event.preventDefault();

    // Event: Prevents Event Bubbling To Parent Elements
    event.stopPropagation();

    // Check Form Validity
    if (formRef.current && formRef.current.checkValidity()) {
      // Validate Form
      setValidated(true);

      // Redux: Send Verification Code Request
      dispatch(sendVerificationCodeRequest(email, history));
    }
    else {
      // Do Nothing (Form.Control.Feedback Will Appear)
    }
  };

  return (
    <div>
      <NavigationBar />

      <Container id="forgot-password-container">
        <div id="forgot-password-inner-container">
          <div>
            <p id="forgot-password-title">Reset Password</p>
          </div>

          <Form ref={formRef} noValidate validated={validated}>
            <Form.Group controlId="forgot-password-email" className="form-group-container">
              <Form.Label className="form-field-title">Email</Form.Label>

              <Form.Control
                type={'email'}
                placeholder={'Email'}
                className="form-input"
                onChange={(event) => setEmail((event.target.value).toLowerCase())}
                value={email}
                maxLength={50}
                required
              />

              <Form.Control.Feedback type="invalid">Invalid email</Form.Control.Feedback>
            </Form.Group>

            <Button
              variant={'primary'}
              type={'submit'}
              id="login-button"
              onClick={(event) => sendVerificationCode(event)}
            >Send Verification Code</Button>
          </Form>

          <div id="login-sign-up-container">
            <p id="login-need-account-text">Need an account?</p>
            <button id="login-sign-up-button" type="button" onClick={() => history.push('sign-up')}>Sign Up</button>
          </div>
        </div>
      </Container>

      <Footer />
    </div>
  );
};

// Exports
export default ForgotPassword;
1 Answers

If you look at the docs, React Bootstrap's logic is that they actually set the validated prop of the Form to true regardless of whether or not the inputs are valid.

According to the prop definition of validated:

Mark a form as having been validated. Setting it to true will toggle any validation styles on the forms elements.

So to solve your issue, just take out setValidated out of the condition statement and put it somewhere below, for example, event.stopPropagation()

const sendVerificationCode = (event: any) => {
    console.log('Component: sendVerificationCode working')

    // Event: Cancels Event (Stops HTML Default Form Submit)
    event.preventDefault();

    // Event: Prevents Event Bubbling To Parent Elements
    event.stopPropagation();

    setValidated(true);

    ...
Related