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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:30:50