73

I am using Formik in my React Native application. On the login form I have two fields: email and password, both of them are required.

I've written such validation rules:

export const LoginSchema = Yup.object().shape({
  email: Yup.string()
    .email('The email is invalid')
    .required('This field is required'),
  password: Yup.string()
    .min(6, 'The password is too short')
    .max(12, 'The password is too long')
    .required('This field is required'),
});

I need to trigger validation ONLY on form submit and show an error popup. I've read the docs, but can't find a solution because the validation triggers onBlur. How can this be done?

Thanks!

const Login = ({ navigation }) => {
  const [isLoading, setIsLoading] = useState(true);
  const [isVisible, setIsVisible] = useState(false);

  useEffect(() => {
    // Later check for token
    const tokenIsStored = true;

    if (tokenIsStored) {
      setIsLoading(false);
    }
  });

  const onLogin = values => {
    console.log(values, 'on login');

    // Pass value to BE endpoint
    navigation.navigate('Dashboard');
  };

  const onModalClose = () => {
    setIsVisible(false);
  };

  console.log(isVisible);

  if (!isLoading) {
    return (
      <ScrollContainer keyboardShouldPersistTaps="handled">
        <ThemedStatusBar />

        <ThemedModal
          isVisible={isVisible}
          primaryMessage="Log In Failed"
          secondaryMessage="Please check your password"
          btnTitle="OK"
          btnPress={() => onModalClose()}
        />

        <Formik
          initialValues={{ email: '', password: '' }}
          validationSchema={LoginSchema}
          onSubmit={values => onLogin(values)}
        >
          {props => (
            <View>
              <ScrollContainer BackgroundColor={Colors.greyColor} Padding="0px" style={styles.loginForm}>
                <ThemedInput
                  onChangeText={props.handleChange('email')}
                  onBlur={props.handleBlur('email')}
                  value={props.values.email}
                  placeholder="Email"
                  keyboardType="email-address"
                />
                <ThemedInput
                  onChangeText={props.handleChange('password')}
                  onBlur={props.handleBlur('password')}
                  value={props.values.password}
                  placeholder="Password"
                  overrideStyles={styles.loginInputBottom}
                  secureTextEntry
                />
                {props.errors.email && setIsVisible(true)}
              </ScrollContainer>
              <ThemedButton onPress={props.handleSubmit} title="Log In" />
            </View>
          )}
        </Formik>
      </ScrollContainer>
    );
  }
  return <ThemedLoader isLoading />;
};

export default Login;
0

3 Answers 3

132

According to the docs

You can control when Formik runs validation by changing the values of <Formik validateOnChange> and/or <Formik validateOnBlur> props depending on your needs.

Pass to your Formik the props validateOnChange={false} and validateOnBlur={false}

Sign up to request clarification or add additional context in comments.

Comments

44

Yeah. You can do something like this.

<Formik
        initialValues={initialValues}
        validationSchema={validationSchema}
        validateOnChange={false}
        validateOnBlur={false}
        onSubmit={(values, { validate }) => {
            validate(values);
        }}
    >

3 Comments

where is the validate() function coming from?
@anastymous in comment above is generated by Formik from validationSchema.
Latest version of Formik uses validateForm for the FormikHelpers.
25

If you use useFormik hook, the next config should be added

  const formik = useFormik({
    initialValues,
    validationSchema,
    validateOnChange: false, // this one
    validateOnBlur: false, // and this one
    onSubmit: (values) => {
     do something on submit
    },
  });

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.