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

React集成Antd Form无法根据API响应更新组件状态

修复React+Ant Design表单无法从API响应更新Switch和Select的问题

核心问题是你同时维护了Ant Design Form的内置状态(通过fields和formRef)和自定义的独立状态(eventBasedEmailPreference、weeklySummaryEmailPreference等),两个状态源不同步,导致Switch和Select无法正确从API响应更新。

修复步骤

  1. 移除冗余自定义状态
    删除eventBasedEmailPreference、weeklySummaryEmailPreference、weeklyPreferred_day_of_week这些独立状态,完全依赖Form内置状态管理。

  2. 统一API响应到Form字段的映射
    从API获取数据后,直接将响应映射为Form需要的字段格式,通过formRef.current.setFieldsValue设置表单值,无需同步到自定义状态。

  3. 调整Switch组件受控逻辑
    Switch的checked属性直接从Form字段获取,onChange时更新Form字段,不再操作自定义状态。

  4. 优化表单提交逻辑
    直接使用Form提交返回的values,无需处理冗余状态。

修改后的关键代码片段

状态定义部分

// 移除冗余状态
// const [eventBasedEmailPreference, setEventBasedEmailPreference] = useState<boolean>(false);
// const [weeklySummaryEmailPreference, setWeeklySummaryEmailPreference] = useState<boolean>(false);
// const [weeklyPreferred_day_of_week, setWeeklyPreferred_day_of_week] = useState<string | undefined>(undefined);

// 保留必要状态,字段命名更清晰
const [fields, setFields] = useState<any>({
  eventBasedEmail: false,
  weeklySummaryEmail: false,
  preferred_day_of_week: undefined,
});

API响应处理的useEffect

useEffect(() => {
  getRequiredActionsCount();
  getUserNotificationPreference.request(Number(user.UserId)).then((res) => {
    if (Array.isArray(res.data) && res.data.length > 0) {
      setUserNotificationData(res.data);
      // 映射API响应到Form字段
      const formValues: any = {
        eventBasedEmail: false,
        weeklySummaryEmail: false,
        preferred_day_of_week: undefined,
      };
      
      res.data.forEach(item => {
        if (item.notification_name === "Event Based Email") {
          formValues.eventBasedEmail = item.preference_value;
        } else if (item.notification_name === "Weekly Summary Email") {
          formValues.weeklySummaryEmail = item.preference_value;
          formValues.preferred_day_of_week = item.preferred_day_of_week;
        }
      });

      setFields(formValues);
      setIsPreferredDayOfWeekOn(formValues.weeklySummaryEmail);
      setShowCheckboxes(formValues.weeklySummaryEmail);
    }
  });
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

Switch组件修改

// 第一个Switch(Per Action Item)
<Form.Item name="eventBasedEmail" valuePropName="checked" style={{ marginBottom: "0px" }}>
  <Switch
    checked={formRef.current?.getFieldValue('eventBasedEmail') ?? false}
    style={{ fontSize: "14px", transform: "scale(0.8)" }}
    onChange={(checked) => {
      formRef.current?.setFieldsValue({ eventBasedEmail: checked });
    }}
  />
</Form.Item>

// 第二个Switch(Weekly Report)
<Form.Item name="weeklySummaryEmail" valuePropName="checked" style={{ marginBottom: "0px" }}>
  <Switch
    checked={formRef.current?.getFieldValue('weeklySummaryEmail') ?? false}
    style={{ fontSize: "14px", transform: "scale(0.8)" }}
    onChange={(checked) => {
      formRef.current?.setFieldsValue({ weeklySummaryEmail: checked });
      setIsPreferredDayOfWeekOn(checked);
      setShowCheckboxes(checked);
    }}
  />
</Form.Item>

表单提交逻辑调整

const handleModalSave = async (values: any) => {
  const notifications = userNotificationData;
  const payload = [];

  // 处理Event Based Email
  let eventBasedItem = notifications.find(n => n.notification_name === "Event Based Email");
  if (eventBasedItem) {
    payload.push({
      ...eventBasedItem,
      preference_value: values.eventBasedEmail,
      user_id: Number(user.UserId),
    });
  } else {
    payload.push({
      user_id: Number(user.UserId),
      notification_name: "Event Based Email",
      preference_value: values.eventBasedEmail,
    });
  }

  // 处理Weekly Summary Email
  let weeklySummaryItem = notifications.find(n => n.notification_name === "Weekly Summary Email");
  if (weeklySummaryItem) {
    payload.push({
      ...weeklySummaryItem,
      preference_value: values.weeklySummaryEmail,
      preferred_day_of_week: values.weeklySummaryEmail ? values.preferred_day_of_week : null,
      user_id: Number(user.UserId),
    });
  } else {
    payload.push({
      user_id: Number(user.UserId),
      notification_name: "Weekly Summary Email",
      preference_value: values.weeklySummaryEmail,
      preferred_day_of_week: values.weeklySummaryEmail ? values.preferred_day_of_week : null,
    });
  }

  if (payload.length > 0) {
    const response = await putUserNotificationPreference.request(Number(user.UserId), payload);
    if (response.data) {
      console.log("API response:", response.data);
      setUserNotificationData(payload);
      handleModalClose();
    }
  }
};

额外优化建议

  • 给Form字段定义明确的TypeScript接口,避免any类型提升代码健壮性。
  • 使用Ant Design Form的useForm钩子替代createRef,更方便获取表单实例。
  • 通过Form.Item的getValueProps或normalize进一步简化字段处理逻辑。

内容的提问来源于stack exchange,提问作者JustAG33K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:19:51