如何在Formik中输入字段时动态获取错误信息
解决Formik输入时实时显示错误的问题
你的问题核心在于Formik默认需要字段被标记为touched(即失去过焦点)才会显示错误,同时validateOnChange是Formik根组件的配置项,并非<ErrorMessage>的属性,所以你之前的设置没有生效。
下面是两种可行的解决方法:
方法一:调整错误显示逻辑,忽略touched状态
默认<ErrorMessage>会同时校验errors和touched状态,你可以自定义渲染逻辑,只要存在错误就显示:
// 替换原有的<ErrorMessage>组件 <ErrorMessage name="username"> {(msg) => <div className={style.error}>{msg}</div>} </ErrorMessage> // 或者用render属性更灵活控制 <ErrorMessage name="password" render={({ error }) => error && <div className={style.error}>{error}</div>} />
如果担心初始空值就显示必填错误影响体验,可以结合dirty状态判断,仅当用户修改过内容后才展示:
<ErrorMessage name="username"> {(msg) => dirty && <div className={style.error}>{msg}</div>} </ErrorMessage>
方法二:输入时主动标记字段为touched
在<Field>的onChange事件中,同时调用Formik的setFieldTouched方法,让字段一开始输入就被标记为已触摸:
{({ isValid, dirty, isSubmitting, handleChange, handleBlur, values, errors, touched, setFieldTouched // 解构出该方法 }) => ( <Form className={style.form}> <label>Логин</label> <Field type="text" // 注意:HTML输入框没有username类型,需改为text name="username" className={style.input} placeholder="Введите логин..." onChange={(e) => { handleChange(e); setFieldTouched('username', true); // 输入时标记为已触摸 }} /> {/* 密码字段同理 */} <label>Пароль</label> <span className={style.pass}> <Field type="password" name="password" className={style.input} placeholder="Введите пароль..." innerRef={passRef} onChange={(e) => { handleChange(e); setFieldTouched('password', true); }} /> <ErrorMessage name="password" component="div" className={style.error} /> </span> </Form> )}
补充说明
- Formik默认
validateOnChange为true,输入时会自动触发验证,你之前没看到错误是因为touched状态的限制,而非验证未执行。 - 若需要组件挂载时就触发初始验证,可以给Formik根组件添加
validateOnMount={true}配置。
内容的提问来源于stack exchange,提问作者Kamal
相关产品推荐
相关产品推荐

