React+TypeScript中Formik结合Yup验证时Select值重置问题求助
React + TypeScript 中 Formik + Yup Select 组件值不更新/重置问题的解决办法
以下是几个常见的原因及对应的修复方案:
1. 未正确绑定 Formik 的动态值或 onChange 事件
原生 <select> 组件必须确保:
value属性绑定到 Formikvalues对象中的对应字段,而非硬编码的初始值onChange关联 Formik 提供的handleChange方法name属性与初始值对象中的字段名完全一致
示例代码:
import { Formik, Form } from 'formik'; import * as Yup from 'yup'; const validationSchema = Yup.object({ favoriteColor: Yup.string().required('请选择颜色'), }); const initialValues = { favoriteColor: '', // 初始值类型需与option的value一致 }; export default function ColorForm() { return ( <Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={(values) => console.log('提交值:', values)} > {({ values, handleChange, errors, touched }) => ( <Form> <div> <label htmlFor="favoriteColor">偏好颜色</label> <select id="favoriteColor" name="favoriteColor" value={values.favoriteColor} onChange={handleChange} > <option value="">请选择</option> <option value="red">红色</option> <option value="blue">蓝色</option> </select> {errors.favoriteColor && touched.favoriteColor && ( <span style={{ color: 'red' }}>{errors.favoriteColor}</span> )} </div> <button type="submit">提交</button> </Form> )} </Formik> ); }
2. 初始值与 Option 值类型不匹配
如果 Formik 初始值的类型和 <option> 的 value 类型不一致(比如初始值是数字,option 值是字符串),Formik 会因为类型不匹配自动将值重置为初始值。
修复方案:
- 确保初始值和所有 option 的
value类型统一(比如全为字符串或全为数字) - 例如:若 option 的 value 是
"1"(字符串),初始值不能设为1(数字),需改为"1"
3. 第三方 Select 组件(如 Antd Select)的适配问题
第三方组件的 onChange 通常直接返回选中值而非事件对象,此时不能直接用 handleChange,需手动调用 Formik 的 setFieldValue 方法更新字段值。
示例(Antd Select):
import { Formik, Form } from 'formik'; import { Select } from 'antd'; import * as Yup from 'yup'; const validationSchema = Yup.object({ city: Yup.string().required('请选择城市'), }); const initialValues = { city: '', }; export default function CityForm() { return ( <Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={(values) => console.log('提交值:', values)} > {({ setFieldValue, values, errors, touched }) => ( <Form> <div> <label htmlFor="city">所在城市</label> <Select id="city" value={values.city} onChange={(selectedValue) => setFieldValue('city', selectedValue)} placeholder="请选择城市" > <Select.Option value="beijing">北京</Select.Option> <Select.Option value="shanghai">上海</Select.Option> </Select> {errors.city && touched.city && ( <span style={{ color: 'red' }}>{errors.city}</span> )} </div> <button type="submit">提交</button> </Form> )} </Formik> ); }
4. Yup 验证规则与字段类型冲突
如果 Yup 的验证规则要求的类型和字段实际值类型不匹配,验证失败后 Formik 会将值重置为初始值。
修复方案:
- 检查 Yup schema,确保规则类型与字段值类型一致
- 例如:若 Select 的值是字符串,验证规则需用
Yup.string(),而非Yup.number()
5. 误用 enableReinitialize 属性
如果设置了 enableReinitialize={true},当初始值的引用发生变化时,Formik 会重新初始化表单。若初始值来自父组件 props,且 props 频繁变化,可能导致选中值被重置。
修复方案:
- 仅在需要根据 props 更新初始值时使用
enableReinitialize - 确保初始值对象的引用稳定(可使用
useMemo缓存初始值)
内容的提问来源于stack exchange,提问作者Abdul Muhamin Rehman
相关产品推荐
相关产品推荐

