登录表单中Formik字段映射与Yup验证失效问题
问题根源及修复方案
你的代码里有两个核心问题导致字段输入后为空、验证功能失效:
错误将Material UI的TextField当作Formik字段使用
Formik需要字段和自身状态绑定才能同步输入值、触发验证,但你直接把Material UI的TextField重命名为Field,没有建立这种关联,输入内容根本不会同步到Formik的状态池里,自然字段显示为空,验证也无法触发。密码字段缺失
name属性
Formik通过name属性匹配初始值initialValues里的字段,密码字段没加name="password",Formik无法追踪这个字段的状态变化。
修复后的完整代码
import React from 'react'; import { Formik, Form, useField } from 'formik'; import * as yup from 'yup'; import Button from '@material-ui/core/Button'; import TextField from '@material-ui/core/TextField'; // 封装和Formik绑定的Material UI输入框组件 const FormikTextField = ({ label, ...props }) => { const [field, meta] = useField(props); const hasError = meta.touched && meta.error; return ( <TextField {...field} label={label} variant="outlined" error={hasError} helperText={hasError ? meta.error : ''} fullWidth margin="normal" /> ); }; const SignIn = () => { const validation = yup.object({ email: yup .string() .email('请输入有效的邮箱') .required('邮箱不能为空'), password: yup .string() .min(8, '密码长度不能少于8位') .required('密码不能为空'), }); return ( <div style={{ maxWidth: 400, margin: '0 auto', padding: '20px' }}> <h2>登录</h2> <Formik initialValues={{ email: "", password: ""}} validationSchema={validation} onSubmit={(values, { setSubmitting }) => { console.log(JSON.stringify(values, null, 2)); setSubmitting(false); }} > <Form> <FormikTextField id='email' name='email' label='邮箱' type='email' /> <FormikTextField id='password' name='password' label='密码' type='password' /> <Button className='submit' type='submit' variant='outlined' style={{ marginTop: '20px' }} > 登录 </Button> </Form> </Formik> </div> ); } export default SignIn
关键修改说明
- 封装
FormikTextField组件,用Formik的useField钩子获取字段的状态(值、输入事件、失焦事件)和验证信息,绑定到Material UI的输入框上,自动处理错误提示。 - 给密码字段补上
name="password",让Formik能正确关联初始值。 - 把邮箱输入框的
type改为email、密码框改为password,符合表单规范。 - 增加基础样式优化表单布局。
内容的提问来源于stack exchange,提问作者China Sanders
相关产品推荐
相关产品推荐

