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

React+RTKQ表单更新时出现400 Bad Request错误求助

问题描述

我有一个支持新增/更新条目的表单,新增和更新都采用POST请求:URL包含id参数时执行更新操作,无id时执行新增操作。新增功能运行正常,但执行更新时返回400 Bad Request错误,提示部分表单数据为必填项,可我使用的是和新增完全一致的数据结构。

前端组件代码

import Button from "@/components/utils/button/button.component";
import { InputController } from "@/components/utils/input/input-controller.component";
import Modal from "@/components/utils/modal/modal.component";
import { TextAreaController } from "@/components/utils/textarea/textarea-controller.component";
import {
  useAddComplianceRequirementMutation,
  useGetComplianceRequirementByIdQuery,
  useUpdateComplianceRequirementMutation,
} from "@/infrastructure/slice/compliance-requirement.slice";
import { useForm } from "react-hook-form";
import { useParams } from "react-router-dom";

type Props = {
  onClose: () => void;
};
const AddRequirementsGroupModal: React.FC<Props> = ({ onClose }) => {
  const { control, handleSubmit } = useForm();
  const { complianceId, id } = useParams();

  const [addRequirement, { isLoading: isAddLoading }] =
    useAddComplianceRequirementMutation();
  const [updateComplianceRequirement, { isLoading: isUpdateLoading }] =
    useUpdateComplianceRequirementMutation();

  const { data: groupData, isLoading } = useGetComplianceRequirementByIdQuery(
    { id },
    { skip: !id }
  );

  const onSubmit = handleSubmit(async (data) => {
    const sendData = {
      ...data,
      packageId: complianceId,
      type: 1,
      complianceId,
    };
    try {
      if (id) {
        await updateComplianceRequirement({
          ...sendData,
          id,
        });
        onClose();
      } else {
        await addRequirement(sendData);
        onClose();
      }
    } catch (e) {
      console.log(e);
    }
  });

  return (
    <>
      <Modal
        isOpen
        onClose={onClose}
        title="اضافه کردن گروه الزامات"
        isLoading={isLoading}
      >
        <form onSubmit={onSubmit}>
          <InputController
            control={control}
            name="label"
            label="عنوان گروه الزامات"
            requiredInput
            rules={{ required: "لطفا عنوان گروه الزامات را وارد کنید." }}
            defaultValue={groupData?.label}
          />
          <TextAreaController
            control={control}
            name="title"
            defaultValue={groupData?.title}
          />
          <div className="flex gap-2">
            <InputController
              control={control}
              name="value"
              label="وزن گروه الزامات"
              requiredInput
              rules={{ required: "لطفا وزن گروه الزامات را وارد کنید." }}
              type="number"
              defaultValue={groupData?.value}
            />
            <InputController
              control={control}
              name="code"
              label="کد"
              requiredInput
              rules={{ required: "لطفا فصل گروه الزامات را مشخص کنید." }}
              defaultValue={groupData?.code}
            />
          </div>
          <TextAreaController
            control={control}
            name="description"
            label="توضیحات گروه الزامات"
            defaultValue={groupData?.description}
          />
          <div className="flex justify-start gap-2">
            <Button size="sm" loading={isAddLoading || isUpdateLoading}>
              ثبت گروه
            </Button>
            <Button color="danger" onClick={onClose}>
              انصراف
            </Button>
          </div>
        </form>
      </Modal>
    </>
  );
};

export default AddRequirementsGroupModal;

新增请求配置(Redux Toolkit)

addComplianceRequirement: builder.mutation({
      query: (body) => ({
        url: "/packageitem",
        method: "POST",
        body,
      })

更新请求配置(Redux Toolkit)

updateComplianceRequirement: builder.mutation({
      query: ({ id, body }) => ({
        url: `/packageitem/${id}`,
        method: 'POST',
        body,
      })
问题原因与解决方案

问题根源

更新请求的参数结构不匹配:

  • 组件调用updateComplianceRequirement时,传入的是{...sendData, id},把id和所有表单字段放在同一层级
  • 但RTK的更新mutation定义要求参数为{id, body},即表单数据需要包裹在body字段内

这导致mutation发送请求时,body参数为undefined,后端未收到必填的表单数据,因此返回400错误。

解决方案(二选一)

方案1:修改组件中的调用方式

将表单数据放入body字段,匹配mutation的参数要求:

// 原代码
await updateComplianceRequirement({
  ...sendData,
  id,
});

// 修改后
await updateComplianceRequirement({
  id,
  body: sendData,
});

方案2:修改RTK的mutation定义

如果后端期望更新请求的body包含id(部分接口会保留此设计),可调整mutation直接接收完整的body对象:

// 原代码
updateComplianceRequirement: builder.mutation({
  query: ({ id, body }) => ({
    url: `/packageitem/${id}`,
    method: 'POST',
    body,
  })
})

// 修改后
updateComplianceRequirement: builder.mutation({
  query: (body) => ({
    url: `/packageitem/${body.id}`,
    method: 'POST',
    body,
  })
})

此方案无需修改组件中的调用代码。

内容的提问来源于stack exchange,提问作者Mehrdad Karami Jourabi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:44:51