You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:50:15