React Formik表单无报错但提交按钮失效,是否需将输入与按钮设为form直接子元素?
问题描述
我在React项目中使用Formik与Yup构建了如下表单,表单无任何报错信息,但点击注册按钮无法触发表单提交。请问是否必须将输入组件与提交按钮设置为form标签的直接子元素才能正常提交?
const validationSchema = yup.object({ password: yup .string('Enter your password') .min(8, 'Password should be of minimum 8 characters length') .required('Password is required'), }); const formik = useFormik({ initialValues: { password: '', }, validationSchema: validationSchema, onSubmit: (values) => { alert(JSON.stringify(values, null, 2)); }, }); <form onSubmit={formik.handleSubmit} style={{ width:'100%' }}> <div className="relative w-full flex items-center"> <RedditTextField fullWidth type={passwordType} className="mb-5" id="outlined-adornment-password" placeholder="Password" name="password" onChange={formik.handleChange} error={formik.touched.password && Boolean(formik.errors.password)} helperText={formik.touched.password && formik.errors.password} /> </div> <Button type="submit" // onClick={} variant="outlined" style={{ backgroundColor: '#FF5758', color: 'white', width: '100%', height: '50px', border: 'none' }} size="large" endIcon={!isLoading && <SendIcon />} loading={isLoading} > {isLoading ? "Fetching..." : "Sign Up"} </Button> </form>
解决方案
不需要将输入组件和提交按钮作为form标签的直接子元素,嵌套在div等容器里完全不影响表单提交逻辑。你的问题大概率出在以下几个点:
- Formik的
touched状态未更新:当前输入框仅绑定了onChange,未绑定onBlur事件,导致Formik无法识别输入框已被触碰,验证逻辑可能阻塞提交。给RedditTextField添加onBlur={formik.handleBlur}即可同步touched状态。 - Button的
loading属性干扰提交:当isLoading状态异常时,Material-UI的Button可能被自动禁用。可以先检查isLoading初始值是否为false,或者临时移除loading属性测试能否提交。 - 验证未通过但无提示:由于缺少
onBlur,输入框未被标记为touched,错误信息不会显示,导致你误以为无报错,但Formik的验证逻辑实际阻止了提交。
修复后的输入框代码示例:
<RedditTextField fullWidth type={passwordType} className="mb-5" id="outlined-adornment-password" placeholder="Password" name="password" onChange={formik.handleChange} onBlur={formik.handleBlur} // 新增该行,同步touched状态 error={formik.touched.password && Boolean(formik.errors.password)} helperText={formik.touched.password && formik.errors.password} />
你也可以临时移除validationSchema测试onSubmit是否触发,如果能触发,就说明问题出在验证逻辑上,结合上述onBlur的修复即可解决。
内容的提问来源于stack exchange,提问作者Ebrahim Ramadan
相关产品推荐
相关产品推荐

