如何使用 formik 和打字稿、钩子构建自定义 onSubmit 函数

问题描述 投票:0回答:3

我正在使用

useCallback
钩子构建 onSubmit 函数,这将在
formik

中使用

我使用 formik 的组件可能看起来像这样,

  import { useContactForm } from './useContactForm'
  //some functional component
  const customSubmit = .... /some submit function 
  const { initialValues, handleSubmit } = useContactForm(customSubmit); 
  const formik = useFormik({
    initialValues,
    onSubmit: handleSubmit //something like this
  });

  return(
    <form onSubmit ={formik.handleSubmit}>
      <input
         id="email"
         name="email"
         type="email"
         onChange={formik.handleChange}
         value={formik.values.email}
      />
      <input 
         id="password"
         name="password"
         type="password"
         onChange={formik.handleChange}
         value={formik.values.password}
      />
      <button type="submit">Submit</button>
    </form>
  ) 

我的 useContactForm.ts 看起来像这样。 // 使用ContactForm.ts

import { useCallback } from 'react';

interface IContactFormFields {
  email: string,
  password: string
}
type ISubmitFormType = (value: IContactFormFields, e?: React.FormEvent<HTMLFormElement>) => Promise<void>;

const useContactForm = (submitForm: ISubmitFormType) => {
  const handleSubmit = useCallback(
    ( formFields : IContactFormFields ) => {
      return submitForm(formFields).then(() => {
        console.log('form submitted');
      })
    },[]);

  const initialValues: IContactFormFields = {
    email: "",
    password: "",
  };
  return {
    handleSubmit,
    initialValues,
  }
}

export default useContactForm;

我的问题

useContactForm
应该得到自定义提交函数名称
submitForm
作为参数。

那我的

ISubmitFormType
应该是什么样子呢?

reactjs typescript typescript-typings formik
3个回答
1
投票

在这种情况下如何确定类型。

  • 什么是变量(函数、整数、字符串、空值、数字等)
  • 如果它是一个函数,传入什么参数,返回什么,以及如何使用返回值。

从你的例子来看,如何使用 submitForm:

submitForm(formFields).then(() => {
        console.log('form submitted');
      })

是函数吗?:是

  • 到目前为止的类型:
    () => unknown

里面有什么:

formFields

  • 到目前为止的类型:
    (formFields) => unknown

返回的是:A

Promise

  • 到目前为止的类型:
    (formFields) => Promise<unknown>

我们目前拥有的:

type ISubmitFormType = (formFields: unknown) => Promise<unknown>

(submitForm: ISubmitFormType) => {...}

0
投票

我的“自定义 onSubmit”只需要传递给它的额外数据。 Formik 的 github 上有一个对我有用的答案。 因此,如果有人在通过 Formik onSubmit 或 handleSubmit 传递自定义数据时遇到问题,请查看以下内容: https://github.com/jaredpalmer/formik/issues/1900#issuecomment-645034575


0
投票

我可能来不及了,但我发现你的问题很有趣,我试着解决它。

这是我的解决方案:

  1. 首先,因为无论如何你都无法获得 FormEvent,我用 formik 为你的
    useContactForm
    钩子替换了更有用的功能:
// use-contact-form.ts

import { FormikConfig, FormikHelpers } from "formik";
import { useCallback } from "react";

export interface IContactFormFields {
  email: string;
  password: string;
}

export type ISubmitFormType = FormikConfig<IContactFormFields>["onSubmit"];

const useContactForm = (submitForm: ISubmitFormType) => {
  const handleSubmit: ISubmitFormType = useCallback(
    async (
      formFields: IContactFormFields,
      formikBag: FormikHelpers<IContactFormFields>
    ) => {
      const result = await submitForm(formFields, formikBag);
      console.log("form submitted");
      return result;
    },
    []
  );

  const initialValues: IContactFormFields = {
    email: "",
    password: "",
  };

  return {
    handleSubmit,
    initialValues,
  };
};

注意

ISubmitFormType
类型。我们只需要使用 formik 自己提供的即可。

  1. 之后,您可以定义自定义提交功能,您还可以像往常一样访问
    formikHelper
    api。
// custom-submit-fn.ts

import { ISubmitFormType } from "./use-contact-form";

const customSubmitFn: ISubmitFormType = async (values, formikHelpers) => {
  // do something
};

export default customSubmitFn;
  1. 最后,您可以将它们拼接在您的组件上
// contact-form.tsx

import { useFormik } from "formik";
import { useContactForm } from "./use-contact-form";
import { customSubmitFn } from "./custom-submit-fn";

export default function FunctionalContactForm() {
  const { initialValues, handleSubmit } = useContactForm(customSubmitFn);
  const formik = useFormik({
    initialValues,
    onSubmit: handleSubmit, //something like this
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <input
        id="email"
        name="email"
        type="email"
        onChange={formik.handleChange}
        value={formik.values.email}
      />
      <input
        id="password"
        name="password"
        type="password"
        onChange={formik.handleChange}
        value={formik.values.password}
      />
      <button type="submit">Submit</button>
    </form>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.