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
相关产品推荐
相关产品推荐

