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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:09:21