React RTK Query提交表单至DRF时提示必填字段错误
问题:React + RTK Query 向 Django Rest Framework POST 数据时返回字段必填错误
问题详情
尝试通过React结合RTK Query向Django Rest Framework后端提交POST请求,控制台显示表单所有字段已填充,但后端始终返回"This field is required."错误。
代码实现
CreateCampaign.js
import React, { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { money } from "../data"; import { CustomButton, FormField, Loader } from "../components"; import { useCreateCampaignMutation } from "../utils/userAuthApi"; import { getToken } from "../utils/index"; const CreateCampaign = () => { const navigate = useNavigate(); const { access_token } = getToken(); const [createCampaign, { isLoading }] = useCreateCampaignMutation(); const [form, setForm] = useState({ title: "", description: "", target: "", deadline: "", }); const handleFormFieldChange = (fieldName, e) => { setForm({ ...form, [fieldName]: e.target.value }); console.log(form); }; const handleSubmit = async (e) => { e.preventDefault(); console.log({ form, access_token }); const res = await createCampaign({ form, access_token }); if (res.data) { console.log(res.data); } else { console.log(res.error.data.errors); } }; return ( <div className="bg-[#1c1c24] flex justify-center items-center flex-col rounded-[10px] sm:p-10 p-4"> {isLoading && <Loader />} <div className="flex justify-center items-center p-[16px] sm:min-w-[380px] bg-[#3a3a43] rounded-[10px]"> <h1 className="font-epilogue font-bold sm:text-[25px] text-[18px] leading-[38px] text-white"> Start a Campaign </h1> </div> <form onSubmit={handleSubmit} className="w-full mt-[65px] flex flex-col gap-[30px]" > <div className="flex flex-wrap gap-[40px]"> {/* <FormField labelName="Your Name *" placeholder="John Doe" inputType="text" value={form.owner} handleChange={(e) => handleFormFieldChange("owner", e)} /> */} <FormField labelName="Campaign Title *" placeholder="Write a title" inputType="text" value={form.title} handleChange={(e) => handleFormFieldChange("title", e)} /> </div> <FormField labelName="Story *" placeholder="Write your story" isTextArea value={form.description} handleChange={(e) => handleFormFieldChange("description", e)} /> <div className="w-full flex justify-start items-center p-4 bg-[#8c6dfd] h-[120px] rounded-[10px]"> <img src={money} alt="money" className="w-[40px] h-[40px] object-contain" /> <h4 className="font-epilogue font-bold text-[25px] text-white ml-[20px]"> You will get 100% of the raised amount </h4> </div> <div className="flex flex-wrap gap-[40px]"> <FormField labelName="Goal *" placeholder="ETH 0.50" inputType="text" value={form.target} handleChange={(e) => handleFormFieldChange("target", e)} /> <FormField labelName="End Date *" placeholder="End Date" inputType="date" value={form.deadline} handleChange={(e) => handleFormFieldChange("deadline", e)} /> </div> <div className="flex justify-center items-center mt-[40px]"> <CustomButton btnType="submit" title="Submit new campaign" styles="bg-[#1dc071]" /> </div> </form> </div> ); }; export default CreateCampaign;
userAuthApi.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' // Define a service using a base URL and expected endpoints export const userAuthApi = createApi({ reducerPath: 'userAuthApi', baseQuery: fetchBaseQuery({ baseUrl: 'http://127.0.0.1:8000/'}), endpoints: (builder) => ({ createCampaign: builder.mutation({ query: ({ campaignData, access_token }) => { return { url: 'campaigns/create/', method: 'POST', body: campaignData, headers: { 'authorization': `Bearer ${access_token}`, } } } }), }) })
服务器返回错误
{"title":["This field is required."],"description":["This field is required."]}
解决方案
核心问题
RTK Query的createCampaign mutation定义时接收的参数是{ campaignData, access_token },但实际调用时传递的是{ form, access_token },参数名称不匹配导致后端无法正确解析到title、description等字段,因此返回必填错误。
修复方式(二选一)
- 修改调用时的参数名:在
handleSubmit方法中,将form重命名为campaignData:
const res = await createCampaign({ campaignData: form, access_token });
- 修改mutation的参数定义:将
campaignData改为form,保持和调用时一致:
createCampaign: builder.mutation({ query: ({ form, access_token }) => { return { url: 'campaigns/create/', method: 'POST', body: form, headers: { 'authorization': `Bearer ${access_token}`, } } } }),
额外检查点
- 确认Django Rest Framework的序列化器中,
title、description等字段名称与前端传递的完全一致,无拼写错误; - 可通过浏览器开发者工具的Network标签,查看POST请求的
Payload或Form Data,确认发送的数据结构是否符合后端要求。
内容的提问来源于stack exchange,提问作者JHAN
相关产品推荐
相关产品推荐

