ES6、React 和 Formik 返回 SetSubmitting

ES6, React and Formik Returning SetSubmitting

我在设置 formiksetSubmitting 函数时遇到问题。 基本上,我有三个提交条件,具体取决于 formik.values...

问题是一旦我点击提交按钮 setSubmitting 就已经触发,所以我想我需要 return 对 onCreateProductconfirmOverwriteProduct 的成功响应] 这样我就可以成功地将 setSubmitting 设置为 false。

我的问题是我该怎么做,因为 onCreateProductconfirmOverwriteProduct 在不同的组件上。

Index.js

const Index = () => {
  const confirmOverwriteProduct = (overwriteDataToSubmit) => {
    dispatch(
      overwriteProduct({
        data: overwriteDataToSubmit,
        callback: function (result) {
          if (result === "error") {
            setSelectedDetails({
              content: "Error overwriting!",
              status: "error",
            });
            setOpenSnackbar(true);
          }
          if (result === "success") {
            setSelectedDetails({
              content: "Overwritten successfully!",
              status: "success",
            });
            setOpenSnackbar(true);
          }
        },
      })
    );
    setConfirmationDialog(false);
  };

  const onCreateProduct = (createProductDataToSubmit) => {
    dispatch(
      createProduct({
        data: createProductDataToSubmit,
        callback: function (result) {
          if (result === "error") {
            setSelectedDetails({
              content: "Error creating product!",
              status: "error",
            });
            setOpenSnackbar(true);
          }
          if (result === "success") {
            setSelectedDetails({
              content: "Product created successfully!",
              status: "success",
            });
            setOpenSnackbar(true);
          }
        },
      })
    );
    setConfirmationDialog(false);
  };

  return <Product />;
};

export default Index;

Product.js

const Product = () => {


  const formik = useFormik({
    initialValues: {
      productCode: product?.productCode || "",
      productImages: product?.productImages || [],
    },
    enableReinitialize: true,
    validationSchema: productSchema,
    onSubmit: (values, { setSubmitting }) => {
      const overwriteDataToSubmit = {
        productIndex,
        imageSlotMap: values.productImages?.map(
          ({ pk = "", newContentSlot = "" }) => ({
            pk,
            slotNumber: newContentSlot,
          })
        ),
      };

      const createProductDataToSubmit = {
        productIndex,
        imageSlotMap: values.productImages?.map(
          ({ pk = "", newContentSlot = "" }) => ({
            pk,
            slotNumber: newContentSlot,
          })
        ),
        ean: values?.productCode
      };


      if (formik.values.productStatusAfterAction)
        return confirmOverwriteProduct(overwriteDataToSubmit);

      if (formik.values.productExisting)
        return confirmOverwriteProduct(overwriteDataToSubmit);

      if (!formik.values.productExisting)
        return onCreateProduct(createProductDataToSubmit);

      setSubmitting(false);
    },
  });

  return ...else.

}

export default Product

不是我的初始答案,但你可以将 setSubmitting 传递给每个方法:

const Product = ({ confirmOverwriteProduct, onCreateProduct }) => {
  const formik = useFormik({
    onSubmit: (values, { setSubmitting }) => {
      if (values.productStatusAfterAction || values.productExisting)
        confirmOverwriteProduct(values, setSubmitting);

      if (!values.productExisting)
        onCreateProduct(values, setSubmitting);
    },
  });
}

然后您可以执行您的操作并手动设置 setSubmitting(false)

const onCreateProduct(values, setSubmitting) => {
   console.log(values);
   setSubmitting(false);
}

const confirmOverwriteProduct(values, setSubmitting) => {
   console.log(values);
   setSubmitting(false);
}

你可以在这个codesandbox

中找到一个例子

当您 return 一个 Promise 时,您不必显式重置 isSubmitting()

const Parent = () => {
  const simpleTimeoutPromise = () =>
    new Promise((res) => {
      setTimeout(() => res("result"), 1000);
    });

  return (
    <Child simpleTimeoutPromise={simpleTimeoutPromise} />
  );
};

const Child = ({ simpleTimeoutPromise }) => (
  <Formik
    initialValues={{ input: "" }}
    onSubmit={(values) => simpleTimeoutPromise()}
  >
    {({ handleChange, values, isSubmitting, handleSubmit }) => (
       <form onSubmit={handleSubmit}>
          <label htmlFor="input">input</label>
          <input
            type="text"
            value={values.input}
            onChange={handleChange}
          />
          <button type="submit" disabled={isSubmitting}>
            Submit
          </button>
        </form>
     )}
  </Formik>
);

更多细节和测试方法在此codesandbox