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

React新手求助:Formik表单提交时onSubmit应传递什么?

嘿,我来帮你搞定这个Formik的提交问题!核心思路很简单——让LoginForm只负责表单的渲染和值收集,把提交逻辑完全交给父组件(也就是你的App组件)来处理,这样就能保证组件的复用性啦。

具体修改步骤:

1. 完善LoginForm组件的Formik提交回调

你需要让Formik内部的onSubmit把收集到的表单值(甚至Formik自带的操作工具actions)传递给父组件传入的onSubmit函数。这样父组件就能拿到表单数据,执行自己的提交逻辑。

修改后的LoginForm代码:

import { Formik, Form, Field, FormikActions } from 'formik';
import React from 'react';
import { MyField, Button } from './your-components'; // 记得导入你的自定义组件

interface Values {
  username: string;
  password: string;
}
interface Props {
  // 如果需要用到Formik的actions(比如设置提交状态、重置表单),可以把它也传给父组件
  onSubmit: (values: Values, actions: FormikActions<Values>) => void;
}

export const LoginForm: React.FC<Props> = ({ onSubmit }) => {
  return (
    <Formik 
      initialValues={{ username: "", password: "" }}
      // 这里调用父组件传进来的onSubmit,把表单值和Formik的操作工具都传过去
      onSubmit={async (values, actions) => {
        await onSubmit(values, actions);
      }}
    >
      {({ values }) => (
        <Form>
          <div>
            <Field name="username" placeholder="Username" component={MyField} />
          </div>
          <div>
            <Field type="password" name="password" placeholder="Password" component={MyField} />
          </div>
          <Button type="submit">submit</Button>
        </Form>
      )}
    </Formik>
  );
};

2. 在App组件中编写实际的提交逻辑

现在你可以在App的onSubmit回调里调用外部接口、处理登录逻辑,完全不用修改LoginForm的内部代码:

修改后的App代码:

import React from 'react';
import './style/App.css';
import { LoginForm } from "./login/LoginForm"

function App() {
  const handleLoginSubmit = async (values: {username: string, password: string}, actions) => {
    try {
      // 这里替换成你的实际接口调用(比如用fetch或axios)
      const response = await fetch('/api/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(values),
      });

      if (response.ok) {
        // 登录成功后的操作:比如跳转页面、提示用户
        alert('登录成功!');
        actions.resetForm(); // 用Formik的actions重置表单
      } else {
        // 处理登录失败的情况
        const errorMsg = await response.text();
        alert(`登录失败:${errorMsg || '请检查用户名和密码'}`);
      }
    } catch (error) {
      // 处理网络异常
      alert('网络出错了,请稍后重试');
    } finally {
      // 无论成功失败,都结束提交状态,让按钮恢复可点击
      actions.setSubmitting(false);
    }
  };

  return (
    <div style={{ textAlign: "center" }}>
      <LoginForm onSubmit={handleLoginSubmit} />
    </div>
  );
}

export default App;

为什么这样做?

  • 保持LoginForm的纯粹性:它只负责渲染表单、收集用户输入,不关心提交后要做什么——这样在其他页面复用这个组件时,只需要传不同的onSubmit回调就能实现不同的提交逻辑。
  • 灵活控制表单状态:通过传递Formik的actions,父组件还能控制表单的提交状态(比如设置loading)、重置表单等操作,完全满足复杂场景的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:58:14