React Formik - 仅在表单提交时触发验证

68

我在我的React Native应用程序中使用Formik。在登录表单上,我有两个字段:电子邮件和密码,它们都是必填的。

我编写了以下验证规则:

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

我需要在表单提交时仅触发验证并显示错误弹出窗口。我已经阅读了文档,但找不到解决方案,因为验证会在失焦事件上触发。应该如何实现?

谢谢!

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;
3个回答

131
根据文档,您可以通过改变<Formik validateOnChange>和/或<Formik validateOnBlur>属性的值来控制Formik何时运行验证,具体取决于您的需求。将validateOnChange={false}validateOnBlur={false}作为props传递给您的Formik组件。

1
这对于v1版本也是一样的吗? - Naveen Vignesh
1
@NaveenVignesh 是的 - Vencovsky
1
不幸的是,这在2.2.6中不起作用...除非您同时禁用验证才行。 - doublejosh
1
@doublejosh,你有一个可行的示例可以展示吗?这也可能是Formik的一个错误。也许你可以在存储库上开一个问题或寻找一个。 - Vencovsky
太令人沮丧了,请提供代码! - loekTheDreamer

40

是的。你可以做类似这样的事情。

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

validate() 函数来自哪里? - anastymous
@anastymous 在上面的评论中是由 Formik 从 validationSchema 生成的。 - Deykun

23
如果您使用useFormik钩子,应添加下一个配置
  const formik = useFormik({
    initialValues,
    validationSchema,
    validateOnChange: false, // this one
    validateOnBlur: false, // and this one
    onSubmit: (values) => {
     do something on submit
    },
  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接