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

React+TypeScript中Formik结合Yup验证时Select值重置问题求助

React + TypeScript 中 Formik + Yup Select 组件值不更新/重置问题的解决办法

以下是几个常见的原因及对应的修复方案:

1. 未正确绑定 Formik 的动态值或 onChange 事件

原生 <select> 组件必须确保:

  • value 属性绑定到 Formik values 对象中的对应字段,而非硬编码的初始值
  • 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:31:46