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

React旅行日志表单:提交时随机ID不变及删除后无法新增问题

问题分析与修复方案

问题1:ID字段提交时未更新

  • 原因:初始useState里的ID是组件首次挂载时生成的固定值,后续提交表单时没有重新生成新ID,导致每次提交都复用同一个旧ID。
  • 修复:在提交表单的函数里,创建新条目时实时生成新ID,而非依赖初始状态里的旧值。

问题2:删除条目后无法新增

  • 原因:
    1. 直接修改导入的静态data数组,这不属于React状态范畴,React无法监测到该数组的变化,删除操作会导致数据状态混乱。
    2. 表单的entry初始值设为数组,但handleChange里将其处理成对象,状态类型不一致导致提交时数据结构错误。
    3. 提交后未重置表单状态,后续提交的是旧表单数据。
  • 修复:
    • 用useState管理日志列表,替代直接操作静态data数组。
    • 修正entry的初始状态为单个空对象,保证状态类型统一。
    • 提交完成后重置表单为初始空状态。

完整修正代码

import React, { useState } from "react";
import Card from "./Card";
import initialData from "./data"; // 重命名避免和状态变量冲突

function Entry(props) {
  // 用useState管理日志列表,初始值为导入的原始数据
  const [entriesList, setEntriesList] = useState([...initialData]);
  
  // 表单状态改为单个空对象,类型统一
  const [entry, setEntry] = useState({
    title: "",
    location: "",
    googleMapsUrl: "",
    startDate: "",
    endDate: "",
    description: "",
    imageUrl: "",
    id: "" // 初始无需赋值,提交时生成
  });

  function handleChange(e) {
    setEntry((prevState) => ({
      ...prevState,
      [e.target.name]: e.target.value
    }));
  }

  function handleSubmit(e) {
    e.preventDefault();

    // 提交时生成新的唯一ID
    const newEntry = {
      ...entry,
      id: Math.random() * 100000000
    };

    // 更新日志列表,将新条目插入开头
    setEntriesList(prevList => [newEntry, ...prevList]);

    // 重置表单状态为初始空值
    setEntry({
      title: "",
      location: "",
      googleMapsUrl: "",
      startDate: "",
      endDate: "",
      description: "",
      imageUrl: "",
      id: ""
    });
  }

  return (
    <div>
      <form className="entry-form" onSubmit={handleSubmit}> {/* 表单直接绑定onSubmit,无需给按钮单独加onClick */}
        <h1 className="entry-title">Add another Travel Memory</h1>
        <div className="journal-entry">
          <input
            className="entry-input"
            type="text"
            value={entry.location}
            name="location"
            placeholder="LOCATION"
            onChange={handleChange}
            required
          />

          <input
            className="entry-input"
            type="text"
            name="title"
            value={entry.title}
            placeholder="LANDMARK"
            onChange={handleChange}
            required
          />
          <input
            className="entry-input"
            type="text"
            name="googleMapsUrl"
            value={entry.googleMapsUrl}
            placeholder="GOOGLE MAPS LINK"
            onChange={handleChange}
            required
          />

          <input
            className="entry-input"
            type="date"
            value={entry.startDate}
            name="startDate"
            onChange={handleChange}
            required
          />
          <input
            className="entry-input"
            type="date"
            value={entry.endDate}
            name="endDate"
            onChange={handleChange}
            required
          />
          <textarea
            className="entry-input"
            placeholder="ADD YOUR STORY OR A FUN FACT FROM YOUR JOURNEY"
            name="description"
            value={entry.description}
            onChange={handleChange}
            required
          />
          <input
            className="entry-input"
            type="text"
            name="imageUrl"
            value={entry.imageUrl}
            placeholder="ADD A IMAGE LINK TO REMIND YOU OF YOUR TRAVEL"
            onChange={handleChange}
          />
          <button type="submit" className="entry-btn">
            add your travel memory
          </button>
        </div>
      </form>
      {/* 将状态管理的日志列表传给Card组件 */}
      <Card data={entriesList} />
    </div>
  );
}

export default Entry;

额外优化建议

  • Math.random()生成的ID存在极小概率重复,生产环境可使用浏览器原生API crypto.randomUUID(),或第三方库如uuid生成更可靠的唯一ID。
  • 表单重置逻辑可提取为单独函数,减少代码重复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 11:03:19