在useEffect中使用Formik使用setErrors方法

时间:2019-12-23 17:38:58

标签: reactjs formik

我有一个Formik组件

<Formik
          initialValues={initialValues}
          enableReinitialize
          onSubmit={(values, { setSubmitting, setErrors }) => {
            handleSubmitForm(values, id);
            setSubmitting(false);
          }}
        >

我需要处理来自API的验证,但是我的请求和错误操作不同,因此我需要使用useEffect来处理错误。 如何在setErrors外部或onSubmit钩子中使用Formik的useEffect方法,如下所示:

useEffect(() => {
  setErrors({...error})
}, [error])

1 个答案:

答案 0 :(得分:0)

我已经解决了这样的问题: 我将这样添加到我的handleSubmitForm async属性中:

const handleSubmitForm = async (data, id) => {
 ...
}

不是,它返回一个promise,并在函数组件之外添加了全局变量let errorResolver = null;,并添加了useEffect

useEffect(() => {
    if (!isEmpty(error)) {
      if (errorResolver) {
        errorResolver(error);
      }
    }
  }, [error]);

然后我像这样重构了onSubmit

onSubmit={(values, { setSubmitting, setErrors }) => {
            handleSubmitForm(values, id).then(() => {
              new Promise(resolve => {
                errorResolver = resolve;
              }).then(response => {
                let errorObj = {};
                response.map(item => {
                  errorObj = { ...errorObj, ...item };
                });
                setErrors(errorObj);
              });
            });
            setSubmitting(false);
          }}

所以现在当我执行onSubmit时,它将仍然等待错误对象接收值。 最终组件如下所示:

import React, { useEffect } from 'react';
import { isEmpty } from 'lodash';
import { Form, Formik } from 'formik';

let errorResolver = null;
export default function TableDataManager({ error, handleSubmitForm }) {
  useEffect(() => {
    if (!isEmpty(error)) {
      if (errorResolver) {
        errorResolver(error);
      }
    }
  }, [error]);
  return (
    <Formik
      onSubmit={(values, { setSubmitting, setErrors }) => {
        handleSubmitForm(values, id).then(() => {
          new Promise(resolve => {
            errorResolver = resolve;
          }).then(response => {
            let errorObj = {};
            // eslint-disable-next-line array-callback-return
            response.map(item => {
              errorObj = { ...errorObj, ...item };
            });
            setErrors(errorObj);
          });
        });
        setSubmitting(false);
      }}
    >
      ...
    </Formik>
  )
}

不确定最好的解决方案,但是它可以工作。