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

如何为动态表单设置数组状态以存储N条输入数据?

解决方案

1. 初始化表单状态

用对象存储表单块数据(键为表单块ID,便于快速定位更新),后续再转成API需要的数组格式:

import { useState, useEffect } from 'react';

// 假设你的表单块数据结构类似这样
// const cards = [
//   { id: 1, data: [{ id: 11, question: "问题1" }, { id: 12, question: "问题2" }] },
//   { id: 2, data: [{ id: 21, question: "问题3" }] }
// ];

const YourFormComponent = () => {
  // 初始化表单状态:键为表单块ID,值为包含id和values的对象
  const [formData, setFormData] = useState({});

  // 可选:如果有初始表单块数据,提前初始化空答案
  useEffect(() => {
    const initialData = {};
    cards.forEach(card => {
      initialData[card.id] = {
        id: card.id,
        values: card.data.map(item => ({ question: item.question, answer: '' }))
      };
    });
    setFormData(initialData);
  }, [cards]);

2. 实现handleChanges函数

接收表单块ID、问题ID、问题文本和输入值,精准更新对应表单块的问题答案:

const handleChanges = (cardId, questionId, questionText, answer) => {
    setFormData(prev => {
      // 获取当前表单块的数据,不存在则创建新块
      const currentCard = prev[cardId] || { id: cardId, values: [] };
      // 找到当前问题在values中的索引(用问题ID匹配更可靠,避免问题文本重复)
      const questionIndex = currentCard.values.findIndex(v => v.question === questionText);

      if (questionIndex !== -1) {
        // 已有该问题,更新答案
        currentCard.values[questionIndex].answer = answer;
      } else {
        // 无该问题,新增问题-答案项
        currentCard.values.push({ question: questionText, answer });
      }

      // 返回新的状态对象
      return { ...prev, [cardId]: currentCard };
    });
  };

3. 修正渲染逻辑

传递表单块ID给handleChanges,同时加入输入值回显:

return (
    <div>
      {/* 遍历所有表单块 */}
      {cards.map(card => (
        <div key={card.id}>
          {/* 遍历当前表单块的所有问题 */}
          {card.data?.map((item, key) => (
            <div htmlFor="" className="my-2 d-flex" key={item.id}>
              <div>{item.question}</div>
              <div>
                <Input
                  id={item.id}
                  size="medium"
                  placeholder=""
                  // 回显已输入的答案
                  value={formData[card.id]?.values.find(v => v.question === item.question)?.answer || ''}
                  onChange={(e) =>
                    handleChanges(
                      card.id, // 传入表单块ID
                      item.id,
                      item.question,
                      e.target.value
                    )
                  }
                />
              </div>
            </div>
          ))}
        </div>
      ))}

      {/* NEXT按钮,点击时构造payload并调用API */}
      <button onClick={() => {
        // 将对象转成API需要的数组格式
        const payload = Object.values(formData);
        // 调用API
        // api.saveFormData(payload);
        console.log('请求payload:', payload);
      }}>NEXT</button>
    </div>
  );
};

export default YourFormComponent;

关键说明

  • 用对象存储状态避免了更新时遍历整个数组,提升了性能;
  • 点击NEXT时通过Object.values(formData)直接得到符合要求的数组结构;
  • 加入输入值回显逻辑,确保用户输入后页面能正确展示内容;
  • 若问题文本可能重复,建议在values对象中加入问题ID,用ID匹配更精准。

内容的提问来源于stack exchange,提问作者Abdur Rehman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 04:30:56