Formik onSubmit - 删除表单和成功消息

Formik onSubmit - remove form and success message

这是我第一次使用 Formik,我遇到了以下问题: 我使用 Formik 文档中提供的 typescript starter 创建了这个表单,它可以工作,但我想显示一条成功消息并删除表单一次 axios returns with status 200.

所以,
1. 如何定位 axios 调用中的表单引用?通常这就像 e.target 一样简单,但该事件似乎在 Formik 中不可用。
2. 如何访问 Formik 中的表单状态?切换成功消息。

完整代码可在此处获得:https://codesandbox.io/s/throbbing-water-ffl2w

非常感谢。

    <Formik
      initialValues={{
        firstName: "",
        lastName: "",
        email: ""
      }}
      // initialStatus={{ // resetForm(); resets this
      //   sent: "nope"
      // }}
      onSubmit={(
        values: Values,
        { setStatus, setSubmitting, resetForm }: FormikActions<Values>
      ) => {
        axios({
          method: "post",
          url: "https://getform.io/f/15faef97-5703-4799-930d-c3e698c99967",
          data: { email: values.email, values }
        }).then(r => {
          setSubmitting(false);
          setStatus("sent");
          //resetForm();
          console.log("Thanks!");
        });
      }}
      render={() => (
        <Form>
          <label htmlFor="firstName">First Name</label>
          <Field
            id="firstName"
            name="firstName"
            placeholder="John"
            type="text"
          />

          <label htmlFor="lastName">Last Name</label>
          <Field id="lastName" name="lastName" placeholder="Doe" type="text" />

          <label htmlFor="email">Email</label>
          <Field
            id="email"
            name="email"
            placeholder="john@acme.com"
            type="email"
          />

          <button type="submit" style={{ display: "block" }}>
            Submit
          </button>
        </Form>
      )}
    />

render是一个获取props的函数。我看到您使用 setStatus,因此您可以从 props 获取 status 并在表单组件

中进行更改

我推荐的是使用状态来控制在组件中显示的内容(由于某些原因我无法保存 codesandbox):

const BasicForm: React.FC<{}> = () => {
  const [isSent, setIsSent] = React.useState(false);

然后,获取回调:

.then(r =>
...
    setIsSent(true);

终于在你的渲染函数中了

render={({ isSubmitting, status }) =>
          !isSent ?
            <Form> ... </Form>:
            <div>Success</div>

这是 Formik v1.1.2 的过时版本,我不建议使用它,因为有一些 Breaking Changes 例如 render 方法已被 弃用 并将在以后的版本中 删除 。您可能想使用当前版本 v2.1.4

  1. how do I target the form reference inside of the axios call?

Formik 传递 values 对象和其他方法(称为 FormikBag) inside the onSubmit prop. You can pass these value directly to axios without the need to have your own onSubmit or onChange methods. Please note that <Formik> component has other props。这会给你相当完整的 control/access 满足您的需求。也就是说,我建议只使用 Formik state/methods 以避免任何副作用或具有多个状态或处理程序的错误。

v2 一般语法:

<Formik
   initialValues={initialValues}
   // Other Formik props...
   onSubmit = {(Object: form values, Object: Formik Bag ) => {
     // access form values...
   }}
>
 // Access render methods and props (children props)
 {(props) => {
    return (
      <Form>
        <Field> ...
      </Form>
     )
   }
 }
</Formik>

axios 示例:

<Formik
  initialValues={initialValues}
  onSubmit={(values) => {
    console.log(values) // Object holds your form values
    axios({
      method: "post",
      url: "url",
      data: { values }
    })
  })
/>

  1. how do I access the state of the form in Formik? to toggle the success message.

你可以使用 Formik setStatus method from FormikBag inside your onSubmit to pass your server response status, then you can access that status via children props 下面是一个例子:


<Formik
  initialValues={initialValues}
  onSubmit={(values, setStatus) => {
    axios({
      method: "post",
      url: "url",
      data: { values }
    })
    .then(res => {
      if (res.status === 200) {
        // 200 means POST method response with success 
        // Pass your server response to Formik
        setStatus({
          sent: true,
          msg: "Message has been sent! Thanks!"
          // Pass more if you need
        })
      }
    })
    .catch(err => {
      // Something went wrong
      setStatus({
        sent: false,
        msg: `Error! ${err}. Please try again later.`
      })
    })
  })
>

  // Later in your code destructuring the children props and use it like so:
  {({ status }) => ( 
    <Form>
      <Field ... />
        {status && status.msg && (
          <p className={`alert ${ status.sent ? "alert-success" : "alert-error"}`}>
            {status.msg}
          </p>
       )}
     <button>Submit</button>
    </Form>
  )}

</Formik>

我确实在这个 codeSandbox 示例中分叉了您的 codesanbox 并更新了依赖项 versions/syntax。请注意,我不是打字专家。