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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:04:56