如何在Formik的initialValues中实现条件赋值?
Formik中实现字段值依赖另一个字段的解决方案
一、先修正初始值的错误写法
你之前的错误写法fieldB: { fieldType: fieldType.FIELDA } ? 'all' : ''问题在于:条件部分是一个非空对象,JS里非空对象永远是"真值",所以不管fieldType实际是什么,fieldB都会被赋值为'all',完全起不到判断作用。
正确的静态初始值写法(如果fieldType初始值固定为FIELDA):
const initialValues: MyValues = { fieldType: fieldType.FIELDA, fieldInformation: '', // 直接用枚举值做相等判断 fieldB: fieldType.FIELDA === fieldType.FIELDA ? 'all' : '', dateRange: { from: lastWeek, to: today, }, };
如果fieldType的初始值是动态的(比如从props传入),可以先定义初始类型变量再生成initialValues:
// 动态获取初始fieldType,比如从props取 const initialFieldType = props.initialFieldType || fieldType.FIELDA; const initialValues: MyValues = { fieldType: initialFieldType, fieldInformation: '', fieldB: initialFieldType === fieldType.FIELDA ? 'all' : '', dateRange: { from: lastWeek, to: today, }, };
二、处理单选切换时的字段同步
initialValues只在组件挂载时生效,当你切换单选按钮改变fieldType后,还需要同步更新fieldB的值,有两种常用方式:
方式1:在单选按钮的onChange事件中直接更新
<Formik initialValues={initialValues} onSubmit={handleSubmit}> {({ setFieldValue }) => ( <Form> {/* FIELDA单选框 */} <label> <Field type="radio" name="fieldType" value={fieldType.FIELDA} onChange={(e) => { setFieldValue('fieldType', e.target.value); // 同步设置fieldB的值 setFieldValue('fieldB', 'all'); }} /> FIELDA </label> {/* FIELDB单选框 */} <label> <Field type="radio" name="fieldType" value={fieldType.FIELDB} onChange={(e) => { setFieldValue('fieldType', e.target.value); // 切换为FIELDB时清空fieldB setFieldValue('fieldB', ''); }} /> FIELDB </label> <Field name="fieldB" /> </Form> )} </Formik>
方式2:用useEffect监听fieldType变化自动同步
适合表单结构复杂、不想在每个单选框写重复逻辑的场景:
import { useFormikContext, useEffect } from 'formik'; // 单独写一个同步组件 const FieldBSync = () => { const { values, setFieldValue } = useFormikContext<MyValues>(); useEffect(() => { // 当fieldType变化时自动更新fieldB setFieldValue('fieldB', values.fieldType === fieldType.FIELDA ? 'all' : ''); }, [values.fieldType, setFieldValue]); return null; }; // 在Formik内部渲染这个同步组件 <Formik initialValues={initialValues} onSubmit={handleSubmit}> <Form> <FieldBSync /> {/* 其他表单字段 */} <Field name="fieldType" type="radio" value={fieldType.FIELDA} /> <Field name="fieldType" type="radio" value={fieldType.FIELDB} /> <Field name="fieldB" /> </Form> </Formik>
内容的提问来源于stack exchange,提问作者Murat K.
相关产品推荐
相关产品推荐

