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

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>
    </>
  );
}

关键说明

  1. 状态拆分:用数组存储历史提交数据,临时对象管理当前输入,避免覆盖已有数据
  2. 提交逻辑:提交时通过扩展运算符[...submittedEducations, currentEducation]追加新条目,符合React状态不可变原则
  3. 表单清空:提交后重置临时对象,让表单回到初始状态
  4. 展示逻辑:遍历已提交数组,逐个渲染Result组件,同时处理空状态提示

内容的提问来源于stack exchange,提问作者Paweł Stępniak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:05:38