React中如何实现多组表单数据的追加存储与展示?
实现多次追加教育信息的方案
核心思路
把原来存储单条教育信息的state拆分为两个:
- 一个数组存储所有已提交的教育条目
- 一个临时对象存储当前表单正在输入的内容
提交时将临时对象追加到数组,同时清空表单,就能支持无限次添加。
修改后的完整代码
主组件代码
import { useState } from 'react'; import TextField from '@mui/material/TextField'; import Button from '@mui/material/Button'; import Result from './Result'; export default function EducationForm() { // 存储所有已提交的教育信息(数组) const [submittedEducations, setSubmittedEducations] = useState([]); // 存储当前表单输入的临时数据(对象) const [currentEducation, setCurrentEducation] = useState({ university: "", degree: "", educationStart: "", educationEnd: "", }); // 处理表单输入变化,更新临时数据 function handleEducationChange(e) { setCurrentEducation({ ...currentEducation, [e.target.name]: e.target.value, }); } // 提交当前教育信息 function handleSubmit() { // 可选:验证表单非空 if (Object.values(currentEducation).some(val => !val.trim())) { alert('请填写完整信息'); return; } // 将临时数据追加到已提交数组 setSubmittedEducations([...submittedEducations, currentEducation]); // 清空当前表单 setCurrentEducation({ university: "", degree: "", educationStart: "", educationEnd: "", }); } return ( <div> {/* 教育信息表单 */} <TextField id="university" label="University" variant="standard" name="university" value={currentEducation.university} onChange={handleEducationChange} /> <br /> <TextField id="degree" label="Degree" variant="standard" name="degree" value={currentEducation.degree} onChange={handleEducationChange} /> <br /> <TextField id="education-start" label="Year You Begun Studies" variant="standard" name="educationStart" value={currentEducation.educationStart} onChange={handleEducationChange} /> <br /> <TextField id="education-end" label="Year You Ended Studies" variant="standard" name="educationEnd" value={currentEducation.educationEnd} onChange={handleEducationChange} /> <br /> <Button variant="contained" onClick={handleSubmit} > 提交教育信息 </Button> {/* 展示所有已提交的教育信息 */} <div style={{ marginTop: '20px' }}> <h3>已提交的教育经历</h3> {submittedEducations.length === 0 ? ( <p>暂无提交记录</p> ) : ( submittedEducations.map((edu, index) => ( <div key={index} style={{ marginBottom: '15px', padding: '10px', border: '1px solid #eee' }}> <Result values={edu} /> </div> )) )} </div> </div> ); }
优化后的Result组件
修正原组件直接渲染数组项的问题,格式化键值对展示:
export default function Result(props) { const educationEntries = Object.entries(props.values); return ( <> <ul> {educationEntries.map(([key, value], index) => ( <li key={index}> <strong>{key.replace(/([A-Z])/g, ' $1').trim()}:</strong> {value} </li> ))} </ul> </> ); }
关键说明
- 状态拆分:用数组存储历史提交数据,临时对象管理当前输入,避免覆盖已有数据
- 提交逻辑:提交时通过扩展运算符
[...submittedEducations, currentEducation]追加新条目,符合React状态不可变原则 - 表单清空:提交后重置临时对象,让表单回到初始状态
- 展示逻辑:遍历已提交数组,逐个渲染Result组件,同时处理空状态提示
内容的提问来源于stack exchange,提问作者Paweł Stępniak
相关产品推荐
相关产品推荐

