React JS & Axios:如何通过FormData提交对象数组
问题:React中处理对象数组的表单输入与提交
我有一个接收对象数组的接口,但不知道如何通过onChange处理用户输入并提交数据。现有代码如下:
const [valuesInput, setValuesInput] = useState({ title: "", question: [{ text: "", values: "" }], category: "", }); const data = new FormData(); data.append("feedback_title", valuesInput.title); data.append("feedback_question", valuesInput.question); data.append("kategori_feedback_id", valuesInput.category); <input key={c} type="text" onChange={(e) => { setValuesInput({ ...valuesInput, question: [{ text: e.target.value, values: e.target.value, }], }); }} />
期望提交的数据格式如下:
"data": [ { "pertanyaan_feedback_id": 1, "kategori_feedback_id": null, "feedback_title": "test", "feedback_question": [ { "values": "dsfdsf", "text": "vvfddf" }, { "values": "dsfdsf", "text": "vvfddf" }, { "values": "dsfdsf", "text": "vvfddf" }, { "values": "dsfdsf", "text": "vvfddf" } ], "created_at": "2022-07-24T04:56:06.000000Z", "updated_at": "2022-07-24T04:56:06.000000Z" } ]
解决方案
一、修复单个问题项的输入更新逻辑
你当前的onChange会把整个question数组重置为只有一个对象,且text和values共用同一个输入值,这不符合需求。需要针对数组的索引来更新对应项的指定字段:
如果是循环渲染question数组中的输入框,写法如下:
{valuesInput.question.map((item, index) => ( <div key={index}> {/* 输入问题文本 */} <input type="text" placeholder="问题文本" value={item.text} onChange={(e) => { // 先拷贝原数组,避免直接修改state const newQuestions = [...valuesInput.question]; // 更新对应索引项的text字段 newQuestions[index].text = e.target.value; setValuesInput({ ...valuesInput, question: newQuestions }); }} /> {/* 输入问题值 */} <input type="text" placeholder="问题值" value={item.values} onChange={(e) => { const newQuestions = [...valuesInput.question]; newQuestions[index].values = e.target.value; setValuesInput({ ...valuesInput, question: newQuestions }); }} /> </div> ))}
二、支持动态添加/删除问题项
如果需要像示例那样生成多个question对象,添加一个“添加问题”按钮,同时给每个问题项加删除按钮:
{/* 添加问题按钮 */} <button type="button" onClick={() => { setValuesInput({ ...valuesInput, // 在原数组末尾新增一个空的问题对象 question: [...valuesInput.question, { text: "", values: "" }] }); }}>添加问题</button> {valuesInput.question.map((item, index) => ( <div key={index}> {/* 上面的输入框 */} {/* 删除按钮 */} <button type="button" onClick={() => { // 过滤掉当前索引的项 const newQuestions = valuesInput.question.filter((_, i) => i !== index); setValuesInput({ ...valuesInput, question: newQuestions }); }}>删除</button> </div> ))}
三、正确提交数组到FormData
直接把数组append到FormData会变成[object Object],接口无法解析。需要把数组序列化为JSON字符串,后端接收后再解析成数组即可:
const data = new FormData(); data.append("feedback_title", valuesInput.title); // 将question数组转为JSON字符串 data.append("feedback_question", JSON.stringify(valuesInput.question)); data.append("kategori_feedback_id", valuesInput.category);
四、完整组件示例
把上述逻辑整合起来,完整的表单组件代码如下:
import { useState } from 'react'; function FeedbackForm() { const [valuesInput, setValuesInput] = useState({ title: "", question: [{ text: "", values: "" }], category: "", }); const handleSubmit = (e) => { e.preventDefault(); const data = new FormData(); data.append("feedback_title", valuesInput.title); data.append("feedback_question", JSON.stringify(valuesInput.question)); data.append("kategori_feedback_id", valuesInput.category); // 替换为你的接口请求逻辑 fetch('/api/submit-feedback', { method: 'POST', body: data }) .then(res => res.json()) .then(result => console.log('提交成功:', result)) .catch(err => console.error('提交失败:', err)); }; return ( <form onSubmit={handleSubmit}> {/* 标题输入 */} <input type="text" placeholder="反馈标题" value={valuesInput.title} onChange={(e) => setValuesInput({...valuesInput, title: e.target.value})} style={{ marginBottom: '10px', display: 'block' }} /> {/* 问题项列表 */} {valuesInput.question.map((item, index) => ( <div key={index} style={{ marginBottom: '10px' }}> <input type="text" placeholder="问题文本" value={item.text} onChange={(e) => { const newQuestions = [...valuesInput.question]; newQuestions[index].text = e.target.value; setValuesInput({...valuesInput, question: newQuestions}); }} style={{ marginRight: '10px' }} /> <input type="text" placeholder="问题值" value={item.values} onChange={(e) => { const newQuestions = [...valuesInput.question]; newQuestions[index].values = e.target.value; setValuesInput({...valuesInput, question: newQuestions}); }} style={{ marginRight: '10px' }} /> <button type="button" onClick={() => { const newQuestions = valuesInput.question.filter((_, i) => i !== index); setValuesInput({...valuesInput, question: newQuestions}); }}>删除</button> </div> ))} {/* 添加问题按钮 */} <button type="button" onClick={() => { setValuesInput({ ...valuesInput, question: [...valuesInput.question, { text: "", values: "" }] }); }} style={{ marginBottom: '10px', display: 'block' }}>添加问题</button> {/* 分类ID输入 */} <input type="text" placeholder="分类ID" value={valuesInput.category} onChange={(e) => setValuesInput({...valuesInput, category: e.target.value})} style={{ marginBottom: '10px', display: 'block' }} /> {/* 提交按钮 */} <button type="submit">提交反馈</button> </form> ); } export default FeedbackForm;
内容的提问来源于stack exchange,提问作者user18088282
相关产品推荐
相关产品推荐

