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
相关产品推荐
相关产品推荐

