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

如何在父组件中获取子组件的Formik表单值?

解决方案:Formik子组件提交后向父组件传递表单字段值

方法一:通过回调函数传递提交后的字段值

这是最直接的实现方式,父组件定义一个接收表单数据的函数并通过props传给子组件,子组件在Formik的onSubmit回调里调用该函数,将需要的字段值回传给父组件。

修改后的父组件代码:

import { useState } from "react";
import ChildForm from "./ChildForm";
import "./styles.css";

export default function App() {
  const [submittedEmail, setSubmittedEmail] = useState("");

  // 接收子组件传递的表单值
  const handleFormSubmit = (formValues) => {
    setSubmittedEmail(formValues.email);
  };

  return (
    <div className="App">
      <ChildForm onFormSubmit={handleFormSubmit} />
      Email Address: {submittedEmail}
    </div>
  );
}

修改后的子组件代码:

import { Formik, Form, Field } from "formik";

const ChildComponent = ({ onFormSubmit }) => {
  return (
    <Formik
      initialValues={{
        firstName: "",
        lastName: "",
        email: "",
      }}
      onSubmit={async (values) => {
        await new Promise((r) => setTimeout(r, 500));
        alert(JSON.stringify(values, null, 2));
        // 调用父组件传递的回调,把表单值传回去
        onFormSubmit(values);
      }}
    >
      <Form>
        <label htmlFor="firstName">First Name</label>
        <Field id="firstName" name="firstName" placeholder="Jane" />

        <label htmlFor="lastName">Last Name</label>
        <Field id="lastName" name="lastName" placeholder="Doe" />

        <label htmlFor="email">Email</label>
        <Field
          id="email"
          name="email"
          placeholder="jane@acme.com"
          type="email"
        />
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  );
};

export default ChildComponent;

方法二:实时同步表单字段值到父组件(可选)

如果需要在用户输入过程中就把字段值同步到父组件,而非仅在提交后,可以利用Formik的onValuesChange回调,实时将指定字段值传递给父组件:

父组件修改:

import { useState } from "react";
import ChildForm from "./ChildForm";
import "./styles.css";

export default function App() {
  const [currentEmail, setCurrentEmail] = useState("");

  return (
    <div className="App">
      <ChildForm onEmailChange={setCurrentEmail} />
      Current Email Address: {currentEmail}
    </div>
  );
}

子组件修改:

import { Formik, Form, Field } from "formik";

const ChildComponent = ({ onEmailChange }) => {
  return (
    <Formik
      initialValues={{
        firstName: "",
        lastName: "",
        email: "",
      }}
      onSubmit={async (values) => {
        await new Promise((r) => setTimeout(r, 500));
        alert(JSON.stringify(values, null, 2));
      }}
      // 监听表单值变化,实时同步email到父组件
      onValuesChange={(values) => {
        onEmailChange(values.email);
      }}
    >
      <Form>
        <label htmlFor="firstName">First Name</label>
        <Field id="firstName" name="firstName" placeholder="Jane" />

        <label htmlFor="lastName">Last Name</label>
        <Field id="lastName" name="lastName" placeholder="Doe" />

        <label htmlFor="email">Email</label>
        <Field
          id="email"
          name="email"
          placeholder="jane@acme.com"
          type="email"
        />
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  );
};

export default ChildComponent;

核心思路

两种方法本质都是利用React单向数据流特性,通过组件props传递回调函数实现数据向上流动。子组件无法直接修改父组件状态,只能通过父组件提供的回调函数传递数据,该逻辑完全适配你使用<Formik>组件的场景,和是否使用useFormik Hook无关。

内容的提问来源于stack exchange,提问作者Jim Parsons

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:45:17