如何将Formik的props传递给{children}子组件,实现提交按钮灵活配置
解决方案
要实现将Formik的状态传递给子组件并灵活配置提交按钮,你可以通过让children接受函数的方式传递所需的Formik属性,同时移除组件内硬编码的提交按钮。以下是具体修改步骤:
1. 修改可复用Form组件
调整Form组件逻辑,不再内置提交按钮,而是将Formik的isSubmitting、isValid、dirty等核心状态通过函数式children传递给使用者:
import { Formik, FormikProps, FormikHelpers } from 'formik'; import { Schema } from 'yup'; // 若未使用yup校验可删除此导入 import React from 'react'; // 用泛型定义Props,替换any提升类型安全性 type FormProps<T> = { initialValues: T; onSubmit: (values: T, actions: FormikHelpers<T>) => void; schema?: Schema<T>; formStyles?: string; // 让children成为接收Formik状态的函数 children: (formikState: Pick<FormikProps<T>, 'isSubmitting' | 'isValid' | 'dirty' | 'handleSubmit'>) => React.ReactNode; }; export const Form = <T extends Record<string, unknown>>({ children, initialValues, onSubmit, schema, formStyles }: FormProps<T>) => { return ( <Formik initialValues={initialValues} onSubmit={onSubmit} validationSchema={schema}> {(formikProps: FormikProps<T>) => { const { handleSubmit, isSubmitting, isValid, dirty } = formikProps; // 调用children函数并传递所需状态 return ( <form className={formStyles} onSubmit={handleSubmit}> {children({ isSubmitting, isValid, dirty, handleSubmit })} </form> ); }} </Formik> ); };
关键修改点:
- 用泛型
T替代any,让组件支持类型校验 - 将
children定义为函数类型,直接接收Formik核心状态 - 移除原有的硬编码提交按钮及相关props(
buttonText、buttonStyles)
2. 修改使用示例
现在你可以在ExampleForm中通过函数式children获取Formik状态,完全自定义提交按钮的位置、样式和逻辑:
const ExampleForm = () => { // 假设initialValues和schema已提前定义 return ( <Form initialValues={initialValues} onSubmit={(values, actions) => { setTimeout(() => { alert(JSON.stringify(values, null, 2)); actions.setSubmitting(false); }, 1000); }} schema={schema} > {/* 通过函数接收Formik状态 */} {({ isSubmitting, isValid, dirty }) => ( <> <div className="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6"> <InputField type="text" label="First name" name="firstName" placeholder="First name" /> <InputField type="text" label="Last name" name="lastName" placeholder="Last name" /> <InputField type="email" label="Email address" name="email" placeholder="Email address" width="col4" /> </div> {/* 自定义提交按钮,直接使用Formik状态 */} <div className="pt-5"> <div className="flex justify-start"> <Button className="your-custom-class" type="submit" isLoading={isSubmitting} disabled={!isValid || !dirty} > 提交表单 </Button> </div> </div> </> )} </Form> ); };
优势:
- 完全掌控提交按钮的位置、样式和状态逻辑
- 可在children中任意使用Formik状态,比如添加表单未修改时的提示文本
- 类型安全,编辑器会自动提示可用的Formik属性
内容的提问来源于stack exchange,提问作者Lee Hitchcock
相关产品推荐
相关产品推荐

