如何为动态表单设置数组状态以存储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
相关产品推荐
相关产品推荐

