Formik Validation Schema阻止onSubmit执行问题排查与解决
Formik表单验证导致提交函数不执行的问题解决
问题原因
你的代码里,Formik实例虽然配置了验证规则,但所有TextField控件都没和Formik的状态、事件绑定。Formik无法获取输入框的真实值,会判定必填字段(name/email/password)为空,触发验证失败,直接拦截提交操作,所以handleSubmit完全不会执行。
正确配置步骤
要让Formik的验证逻辑生效且不阻断正常提交,需要把表单控件和Formik实例做绑定,同时添加错误提示:
1. 给TextField绑定Formik核心属性
每个输入框需要绑定以下属性:
value:关联Formik的对应字段值onChange:绑定Formik的handleChange统一处理输入变更onBlur:绑定Formik的handleBlur触发字段验证error:判断当前字段是否有未处理的错误helperText:显示字段的错误提示文本
2. 修正后的完整代码
interface Props { } export interface RegisterData { name: string; email: string; password: string; status?: boolean } const validationSchema: SchemaOf<RegisterData> = yup.object().shape({ name: yup .string() .max(20, "Name cannot be more than 20 characters") .required("name is required"), email: yup .string() .email("Enter a valid email") .required("Email is required"), password: yup .string() .min(8, "Password should be of minimum 8 characters") .required("Password is required"), status: yup .boolean() .notRequired() }); const Create: React.FC<Props> = () => { const dispatch = useAppDispatch(); const theme = useTheme(); const navigate = useNavigate(); const [checked, setChecked] = useState<boolean>(false); const initialFormValues: RegisterData = { name: "", email: "", password: "" } const handleChecked = (event: any) => { console.log(event.target.checked); setChecked(event.target.checked); } const handleSubmit = async (values: any) => { console.log("hello"); console.log(values); } const formik = useFormik({ initialValues: initialFormValues, validationSchema: validationSchema, onSubmit: handleSubmit }) return ( <Box {...} > <Box component="form" onSubmit={formik.handleSubmit} sx={{ mt: 2 }}> <Grid container spacing={1}> <Grid item xs={12}> <Typography variant="subtitle1" sx={{ color: theme.palette.text.secondary }} > {Constants.Create.NAME_HEADER} </Typography> </Grid> <Grid item xs={12}> <TextField margin="normal" required fullWidth id="name" name="name" label="Name" variant="filled" size="small" sx={{ marginTop: "0px" }} value={formik.values.name} onChange={formik.handleChange} onBlur={formik.handleBlur} error={formik.touched.name && Boolean(formik.errors.name)} helperText={formik.touched.name && formik.errors.name} /> </Grid> <Grid item xs={12}> <Typography variant="subtitle1" sx={{ color: theme.palette.text.secondary }} > {Constants.Create.EMAIL_HEADER} </Typography> </Grid> <Grid item xs={12}> <TextField margin="normal" required fullWidth id="email" name="email" label="Email" variant="filled" size="small" sx={{ marginTop: "0px" }} value={formik.values.email} onChange={formik.handleChange} onBlur={formik.handleBlur} error={formik.touched.email && Boolean(formik.errors.email)} helperText={formik.touched.email && formik.errors.email} /> </Grid> <Grid item xs={12}> <Typography variant="subtitle1" sx={{ color: theme.palette.text.secondary }} > {Constants.Create.PASSWORD_HEADER} </Typography> </Grid> <Grid item xs={12}> <TextField type="password" margin="normal" required fullWidth id="password" name="password" label="Password" variant="filled" size="small" sx={{ marginTop: "0px" }} value={formik.values.password} onChange={formik.handleChange} onBlur={formik.handleBlur} error={formik.touched.password && Boolean(formik.errors.password)} helperText={formik.touched.password && formik.errors.password} /> </Grid> </Grid> <Button type="submit" fullWidth variant="contained" size="large" sx={{ mt: 2, mb: 2 }} > {Constants.Create.CREATE_ACCOUNT} </Button> </Box> </Box> ) }
额外说明
- 绑定
onBlur是为了在用户离开输入框时就触发字段验证,提升用户体验;如果不需要实时验证,也可以只保留onChange,但提交时Formik依然会做全局验证。 - 错误提示的显示依赖
formik.touched,确保只有用户触碰过该字段后才显示错误,避免页面加载就出现一堆错误提示。
内容的提问来源于stack exchange,提问作者code_learner93
相关产品推荐
相关产品推荐

