Formik的onSubmit函数在我的代码中无法正常工作

97
我正在使用React和Formik创建一个表单。以下是我的代码:

我正在使用React和Formik创建一个表单。以下是我的代码:

<div>
  <Formik
    initialValues={{
      email: ""
    }}
    onSubmit={(values: FState, setSubmitting: any) => {
      console.log("Enter in submit function", values);
      setTimeout(() => {
        alert(JSON.stringify(values, null, 2));
        setSubmitting(false);
      }, 500);
    }}
    validationSchema={validationSchemaGlobal}
  >
    {({
      errors,
      touched,
      handleBlur,
      handleChange,
      isSubmitting,
      values,
      handleSubmit
    }: any) => (
      <div>
        <Cards>
          <form onSubmit={handleSubmit}>
            <CardBody>
              <h4>
                Enter Your Email Address and we'll send you a link to reset your
                password
              </h4>
              <Field
                type="text"
                id="email"
                value={values.email}
                component={CustomInput}
                onChange={handleChange}
                onBlur={handleBlur}
              />
              {errors.email && touched.email ? (
                <div style={{ color: "red" }}>{errors.email}</div>
              ) : null}
            </CardBody>
            <CardFooter>
              <br />
              <button type="submit" disabled={isSubmitting}>
                Send Password Reset Link
                {/* {isSubmitting && <i className="fa fa-sponner fa-spin"/>} */}
              </button>
            </CardFooter>
          </form>
        </Cards>
      </div>
    )}
  </Formik>
</div>
在这个formik表单中,onSubmit函数没有起作用。我不知道为什么?请告诉我,大家觉得我的代码有什么问题?

你的意思是它出了问题,还是onSubmit方法根本没有被调用?我认为你应该将onSubmit方法的第二个参数命名为actions,并且使用actions.setSubmitting而不是仅仅的setSubmitting,因为它是一个传递给它的对象,而不是一个函数。 - Tholle
@Tholle 提交表单不起作用。我已经执行了 actions.setSubmitting 但是没有起作用。 - NewCoder
1
我尝试运行了你的代码,并且在去掉你没有提供的部分后,它确实可以工作:https://codesandbox.io/s/formik-example-3kdov?fontsize=14 所以我移除了 component={CustomInput} 并将所有其他自定义组件更改为 div,并更改了验证模式,因为你没有提供你的验证模式。也许问题出在你的 CustomInput 或验证上? - Kiya
2
移除验证模式和检查,我的意思是将validationSchema设置为null。 - Akhil S
我遇到了类似的问题,移除验证模式帮助我解决了它。 我认为我需要检查是否有任何未被评估的字段。 - Piyush Mahapatra
用 Formik 将 <form onSubmit={handleSubmit}> 替换为 <Form>。 - Javier González
17个回答

243

检查您的validationSchema。我遇到了这个问题,并发现我的验证器返回了一些信号,告诉Formik表单无效,但没有其他警告或消息出现。它只是无法提交。

将该属性替换为validator={() => ({})},即仅返回一个空对象。这应该可以通过验证并触发您的onSubmit。然后,您可以从那里恢复功能。

  <Formik
    initialValues={{
      email: ""
    }}
    onSubmit={() => { console.log("submit!"); }}
    validator={() => ({})}
  >
    {/* */}
  </Formik>

14
谢谢,这解决了我的问题!我正在使用 Yup,并设置了一个额外的字段验证,需要该字段,但它没有与任何字段相关联,因此无法通过验证。 - Alex P
@AlexP 嘿,我遇到了类似的问题。请问你是如何解决的? - Yogesh Tripathi
2
应该有某种通知来提示这一点。一点也不明显。 - Leon
1
一个错误不会有影响。感谢Chris发现了这个问题。 - Saurabh Bayani
2
@NickKinlen的建议也帮我解决了这个问题。为了找出问题所在,我添加了以下内容以显示错误:{!isValid && JSON.stringify(errors)} - WaltDe

51
在我的情况下,我使用Yup作为验证器,并且我意外地将firstNamelastName作为必填项加入到了我的validationSchema中,但是我在表单中并没有这些值。
我的validationSchema如下,
const SignupSchema = Yup.object().shape({
  firstName: Yup.string()
    .min(2, 'Too Short!')
    .max(50, 'Too Long!')
    .required('Required'),
  lastName: Yup.string()
    .min(2, 'Too Short!')
    .max(50, 'Too Long!')
    .required('Required'),
  email: Yup.string()
    .email('Invalid email')
    .required('Required'),
  password: Yup.string()
    .min(6, 'Password must be at least 6 characters')
    .max(24, 'Password can be maximum 24 characters')
    .required('Required')
}) 

我刚刚删除了firstNamelastName

const SignupSchema = Yup.object().shape({
  email: Yup.string()
    .email('Invalid email')
    .required('Required'),
  password: Yup.string()
    .min(6, 'Password must be at least 6 characters')
    .max(24, 'Password can be maximum 24 characters')
    .required('Required')
})

所以请检查您的validationSchema,看看是否需要在您的表单中存在某些内容。


6
你刚刚帮我省去了很多麻烦,谢谢。 - Zak DeBrine
1
这个可行,但是想一想,希望它应该忽略那个验证。 - Tilak Raj
2
我浪费了几个小时来弄清楚这个问题。然后偶然发现了这个。谢谢。 - rahulxyz
1
这也是我的问题,我的验证模式属性中有一个错别字,所以我也看不到验证失败的情况。 - Matthew
1
在我的情况下,我将输入名称和初始值从“电子邮件”更改为“用户名”,但忘记更新validationSchema。现在一切都正常工作。 - Guille Acosta

12

我导入的是react-bootstrap中的Form而不是formik,所以出现了这个问题。通过导入formikForm,问题被解决了。有时,直接使用react-bootstrap中的Form.Control而不是formik中的Field也会导致此问题。

如果你确实需要使用Form.Control,可以使用render prop。


对我没用 :( - Nishant Kumar Verma
只有在使用 Bootstrap 表单而不是 Formik 表单时,此方法才有效。 - Bhuwan Adhikari
你能分享一下 rendor prop 的语法吗? - Sachin

6
有点晚回答原问题,但我也遇到了同样的问题,并且找到了容易但难以发现的解决方法。
当我传递"name"属性给组件时,我错误地写成了"DateOfBirth"而不是小写形式,这意味着它与我的validationSchema不匹配。
我的schema看起来像这样:
export const userSchema = yup.object().shape({
firstName: yup.string().min(1).max(50).required('Field is required'), 
lastName: yup.string().min(1).max(50).required('Field is required'), 
dateOfBirth: yup.date().required('Invalid input'),});

这意味着组件的名称必须匹配。

之前(无效):

 <DateTimePicker name="DateOfBirth" label="Date of birth" />

之后(已工作):

<DateTimePicker name="dateOfBirth" label="Date of birth" />

谢谢,伙计!那也是我的问题! - Cleversou

5
在我的情况下,onSubmit 没有起作用是因为我忘记将表单包装在 <form></form> 标签中。这是一个愚蠢的问题,但它可能是此行为的原因。如果上述解决方案无效,请检查是否有 form 标签。

1
我也遇到同样的问题,记性不好! - user11720628
1
难道不应该让<Formik>在你的代码中包装表单吗?天啊,感谢您的回答。 - Kilmazing

4
在我的情况下,错误地将validationSchema传递给了错误的属性。
错误:
  <Formik
    initialValues={initialValues}
    validate={validationSchema} <----- Error
  >

正确的方式:

  <Formik
    initialValues={initialValues}
    validationSchema={validationSchema} <----- Good
  >

2
我提供另一种可能的解决方法,更改按钮类型并添加 onClick 如下:

我是通过更改按钮类型并添加 onClick 来处理的。

<Button type="button" onClick={submitForm}>

在顶部添加submitForm属性以及values,touched等内容。
 {({ submitForm, errors, handleChange, handleSubmit, touched, values }) => (

现在它正在工作。


2

这可能是由于表单被提交但无效,这可能是由于验证模式与您的表单不匹配而导致的多个原因之一。

在我的情况下,这是因为有一个字符串,但它被发送为空。因此,我只需将.nullable()添加到该字段的验证模式中。


2

在我的验证模式(validationSchema)中有一个额外的字段,它是用Yup声明的。然而,由于该字段没有在Formik中声明,所以它无法起作用。将该字段从验证模式中删除后,问题得到解决。


1

我遇到了同样的问题。我的onSubmit函数没有在提交按钮上执行onClick。

问题出在Yup.validation模式中。有一个我没有使用的额外字段。我删除了那个字段,问题迎刃而解。


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