【问题标题】:Formik onSubmit - remove form and success messageFormik onSubmit - 删除表单和成功消息
【发布时间】:2020-03-27 20:33:45
【问题描述】:

这是我第一次使用 Formik,我面临以下问题: 我使用 Formik 文档中提供的 typescript starter 创建了这个表单,它可以工作,但是我想显示一条成功消息并在 axios 返回状态为 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>
      )}
    />

【问题讨论】:

    标签: reactjs typescript axios formik


    【解决方案1】:

    我建议使用状态来控制在组件中显示的内容(由于某种原因我无法保存代码框):

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

    然后,获取回调:

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

    终于在你的渲染函数中

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

    【讨论】:

      【解决方案2】:

      render 是一个获取道具的函数。我看到你使用setStatus,所以你可以从props获取status并在Form Component中进行更改

      【讨论】:

      • 嗨基里尔,感谢您的评论。我尝试将 'props' 和 'FormikProps' 添加到渲染参数 render={( { FormikProps, isSubmitting, status }) =&gt; ( 并收到此错误:Property 'props' does not exist on type 'FormikSharedConfig & FormikState & FormikActions & FormikHandlers & FormikComputedProps & FormikRegistration'
      • render={({ status, isSubmitting }: FormikProps) => (/*. your Form */)}
      【解决方案3】:

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

      1. 如何在 axios 调用中定位表单引用?

      Formikvalues 对象与 onSubmit 属性内的其他方法(称为 FormikBag)一起传递。您可以将这些值直接传递给 axios,而无需拥有自己的 onSubmitonChange 方法。请注意&lt;Formik&gt; 组件还有其他props。这将使您几乎可以完全控制/访问您的需求。也就是说,我建议只使用 Formik 状态/方法以避免任何副作用或具有多个状态或处理程序的错误。

      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. 如何在 Formik 中访问表单的状态?切换成功消息。

      您可以在 onSubmit 中使用 FormikBag 中的 Formik setStatus 方法来传递您的服务器响应状态,然后您可以通过 children props 在此处访问该 status是一个例子:

      
      <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 示例中分叉了您的代码框并更新了依赖项版本/语法。请注意,我不是打字稿专家。

      【讨论】:

      • 感谢 awran5 提供如此详细而有价值的答案。沙箱返回 404,但我可以按照你上面的例子 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多