TypeScript实现基于路由ID自动选中Formik Autocomplete下拉选项
Formik中Autocomplete组件自动选中服务商名称的修复方案
问题核心
当前代码直接修改formInitialValues的方式无法触发Formik状态更新,且Autocomplete组件需要匹配选项列表中的完整对象(或严格一致的字符串)才能自动选中目标值。
修复步骤
1. 修正初始值的状态管理
不要直接修改全局formInitialValues,改用React状态管理Formik初始值,确保serviceProvider变化时触发Formik重新渲染:
const UpdateServiceProviderForm: FC<FormProps> = ({ formRef, validateChange, handleLoading, serviceProvider, }) => { const { AxiosRequest, response, error } = useAxiosRequest(); const [isLoading, setIsLoading] = useState(false); const { alertShow, alertMessage, alertType, setAlert, closeAlert } = useFormAlerts(); // 用state管理初始值,避免直接修改全局对象 const [initialValues, setInitialValues] = useState(formInitialValues); useEffect(() => { if (serviceProvider) { setInitialValues(prev => ({ ...prev, sp_id: serviceProvider.sp_id, sp_allocate_to: serviceProvider.sp_allocate_to, sp_assesor_code: serviceProvider.sp_assesor_code, sp_email_address: serviceProvider.sp_email_address, sp_repair_limit: serviceProvider.sp_repair_limit, sp_limit100_l: serviceProvider.sp_limit100_l, sp_limit150_l: serviceProvider.sp_limit150_l, sp_limit200_l: serviceProvider.sp_limit200_l, sp_limit250_l: serviceProvider.sp_limit250_l, // 补充服务商名称字段赋值(假设字段为sp_name) sp_name: serviceProvider.sp_name })); } }, [serviceProvider]); // ...其他逻辑保持不变 return ( <div> {/* ...其他组件 */} <Formik initialValues={initialValues} // 替换为state变量 validateOnBlur={validateChange} validateOnChange={validateChange} validationSchema={validationSchema} onSubmit={async (values, actions) => { await AxiosRequest.PUT({ url: `/api/v1/serviceproviders/update`, data: values, }); }} innerRef={formRef} > {/* ...表单内容 */} </Formik> </div> ); };
2. 正确配置Autocomplete组件
以Material-UI的Autocomplete为例,确保组件与Formik值正确绑定,匹配选项列表中的完整对象:
// 在Formik的render回调中添加Autocomplete组件 <Grid item xs={12}> <Autocomplete // 服务商选项列表(需确保已加载完成) options={serviceProvidersOptions} // 指定选项显示的标签字段 getOptionLabel={(option) => option.sp_name} // 从选项列表中匹配当前服务商的完整对象 value={serviceProvidersOptions.find(sp => sp.sp_id === serviceProvider.sp_id) || null} // 选中时同步更新Formik字段 onChange={(event, selectedOption) => { setFieldValue('sp_name', selectedOption?.sp_name || ''); setFieldValue('sp_id', selectedOption?.sp_id || ''); }} renderInput={(params) => ( <TextField {...params} name="sp_name" label="服务商名称" fullWidth error={!!errors.sp_name} helperText={errors.sp_name} /> )} /> </Grid>
3. 关键注意事项
- 匹配规则:Autocomplete的
value必须是options数组中的完整对象;若仅传字符串,需确保getOptionLabel返回值与Formik值完全一致(无大小写、空格差异)。 - 选项加载时机:确保
serviceProvidersOptions在组件渲染时已获取数据,可添加loading状态避免空数组导致匹配失败。 - 禁止Mutable操作:不要直接修改Formik的
initialValues或全局对象,必须通过状态更新或setFieldValue触发Formik状态同步。
快速应急方案
若赶截止日期,可跳过状态重构,直接在serviceProvider变化时调用setFieldValue强制更新:
// 在Formik的render回调中获取setFieldValue {({ values, setFieldValue }: FormikProps<any>) => { useEffect(() => { if (serviceProvider) { setFieldValue('sp_id', serviceProvider.sp_id); setFieldValue('sp_name', serviceProvider.sp_name); // 其他字段同步更新... } }, [serviceProvider, setFieldValue]); return ( // ...表单内容 ); }}
内容的提问来源于stack exchange,提问作者Anda Sizani
相关产品推荐
相关产品推荐

