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

React表单编辑时输入框onChange失效,无法保留编辑值

问题描述

我正在开发一个React小型应用,其中包含编辑功能。点击编辑按钮后,系统会加载已有数据,允许用户编辑任意字段并提交。数据获取与表单加载均正常,但编辑文本框时,输入值会自动变回已获取的原有数据,无法保留编辑后的内容。需注意,问题出在表单输入编辑环节而非提交环节。以下是我使用的EditTask组件代码:

import { useState, useEffect } from 'react';
import { json, Link } from 'react-router-dom';
import { useParams } from 'react-router-dom';
const EditTask = ({ onEdit }) => {
  const [text, setText] = useState('');
  const [day, setDay] = useState('');
  const [reminder, setReminder] = useState(false);
  const params = useParams();

  useEffect(() => {
    fetchTask();
  });
  const fetchTask = async () => {
    const res = await fetch(`http://localhost:5000/tasks/${params.id}`);
    const data = await res.json();
    setText(data.text);
    setDay(data.day);
    setReminder(data.reminder);
  };

  const onSubmit = async (e) => {
    e.preventdefault();
    if (!text) {
      alert('Please enter task name');
      return;
    }

    onEdit({ text, day, reminder });
    setText('');
    setDay('');
    setReminder(false);
  };

  const handleChange = ({ target }) => {
    console.log(target.value); // displaying the input value
    setText(target.value); // changes to existing value not the one I entered
  };

  return (
    <form className="add-form" onSubmit={onSubmit}>
      <div className="form-control">
        <label>Task</label>
        <input
          id="AddTask"
          type="text"
          placeholder="Add Task"
          value={text}
          onChange={handleChange}
        />
      </div>
      <div className="form-control">
        <label>Date & Time</label>
        <input
          id="Date"
          type="text"
          placeholder="Date & Time"
          value={day}
          onChange={(e) => setDay(e.target.value)}
        />
      </div>
      <div className="form-control form-control-check">
        <label>Set Reminder</label>
        <input
          id="Reminder"
          type="checkbox"
          checked={reminder}
          value={reminder}
          onChange={(e) => setReminder(e.currentTarget.checked)}
        />
      </div>
      <input className="btn btn-block" type="submit" value="Save Task" />
      <Link to="/">Home</Link>
    </form>
  );
};

export default EditTask;

请问有人能解释我遗漏了什么吗?如需其他信息,我可以提供。期望输入框能保留用户输入的值并正常提交。


解决方案

嘿,这个问题我之前踩过坑!核心问题就出在你的useEffect钩子上——你没给它设置依赖数组。

为什么输入值会被自动重置?

当useEffect没有指定依赖数组时,它会在每次组件渲染时都执行一遍。流程是这样的:

  1. 组件初始化,fetchTask拉取数据并设置状态,表单正常加载原有内容。
  2. 你在输入框打字时,handleChange调用setText更新状态,触发组件重新渲染。
  3. 组件一渲染,无依赖的useEffect就又执行fetchTask,重新从后端拉取原始数据,直接把你刚输入的内容覆盖了!

修复方法

给useEffect加上依赖数组,让它只在params.id变化时才执行fetchTask——也就是只有当你切换到编辑另一个任务时,才重新拉取数据:

useEffect(() => {
  fetchTask();
}, [params.id]); // 添加上这个依赖数组,精准控制执行时机

额外的小细节(顺便提一下,避免后续踩坑)

你的onSubmit函数里有个拼写错误:e.preventdefault()应该是e.preventDefault()(注意大写的D),不然表单会默认提交并刷新页面,导致状态丢失。修改后:

const onSubmit = async (e) => {
  e.preventDefault(); // 修正拼写错误
  if (!text) {
    alert('Please enter task name');
    return;
  }

  onEdit({ text, day, reminder });
  setText('');
  setDay('');
  setReminder(false);
};

这样修改后,你输入的内容就不会被重置了,表单也能正常提交啦!


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:40:39