Next.js13中Formik表单onSubmit未触发问题求助
问题分析与解决方案
你遇到的问题核心有两个:Form组件使用错误,以及验证Schema拼写错误,导致Formik的提交逻辑被跳过,触发了表单默认的GET提交行为。
具体问题点
- Form组件来源错误:如果你的
<Form>是导入自next/form,它会触发Next.js自带的表单提交(默认GET方法),直接跳转到带查询参数的URL,完全绕过Formik的onSubmit。必须使用Formik提供的Form组件。 - 验证Schema拼写错误:代码里的
validationSchame是拼写错误,正确应为validationSchema,这会导致Yup验证完全失效。
修复步骤
导入正确的Form组件
确保从formik库导入Form,而不是next/form:import { Formik, Form, Field } from 'formik';修正Schema拼写
将validationSchame改为validationSchema:<Formik validationSchema={validationSchema} // 修正拼写 initialValues={{ username: "", password: "", }} onSubmit={async (values, formikHelpers) => { console.log(values); }} >确保客户端组件环境
页面顶部的'use client'指令已经正确添加,这部分没问题,Formik只能在客户端组件中运行。
修正后的完整代码示例
'use client'; import { Formik, Form, Field } from 'formik'; import * as Yup from 'yup'; import { Grid, Button } from '@mui/material'; import StyledRedditTextField from './your-styled-component-path'; // 替换为你的组件路径 const validationSchema = Yup.object().shape({ username: Yup.string().required('用户名不能为空'), password: Yup.string().required('密码不能为空'), }); export default function LoginForm() { return ( <Formik validationSchema={validationSchema} initialValues={{ username: "", password: "", }} onSubmit={async (values, formikHelpers) => { console.log(values); // 这里可以添加你的提交逻辑,比如API请求 formikHelpers.setSubmitting(false); }} > {({ errors, touched }) => { // 加入touched控制错误提示时机 return ( <Form> <Grid item sx={{ marginBottom: 1 }}> <Field sx={{ width: "300px" }} name="username" as={StyledRedditTextField} placeholder="Username" label="Username" size="medium" error={touched.username && Boolean(errors.username)} helperText={touched.username && errors.username} /> </Grid> <Grid item> <Field sx={{ width: "300px", marginBottom: 2 }} name="password" as={StyledRedditTextField} placeholder="Password" label="Password" size="medium" type="password" error={touched.password && Boolean(errors.password)} helperText={touched.password && errors.password} /> </Grid> <Grid item> <Button type="submit" variant="contained" color="primary" sx={{ width: "300px" }} size="large" > Sign In </Button> </Grid> </Form> ); }} </Formik> ); }
补充说明:加入touched可以让错误提示在用户触碰输入框后才显示,提升用户体验;formikHelpers.setSubmitting(false)用来在异步操作完成后重置提交状态,避免按钮一直处于加载状态。
内容的提问来源于stack exchange,提问作者Eidris
相关产品推荐
相关产品推荐

