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

React中避免Props作为初始State反模式:Todo项编辑实现方案

解决React组件中props作为初始state的反模式问题

针对你的待办事项组件,要避免将title props作为editedTitle的初始state,可以通过以下方式调整代码:

修改思路

核心是不在组件挂载时用props初始化状态,而是在用户触发编辑操作时,再将当前最新的title props赋值给编辑状态,这样既符合React状态管理的最佳实践,又能保证数据一致性。

修改后的代码

function Task({ id, title, done, onSaveTodo, onDeleteTodo, onDoneTodo }) {
  const [isEditing, setIsEditing] = useState(false);
  // 初始化editedTitle为空,不再依赖props
  const [editedTitle, setEditedTitle] = useState('');

  let todoContent;
  if (isEditing) {
    todoContent = (
      <>
        <input
          value={editedTitle}
          onChange={(e) => setEditedTitle(e.target.value)}
        />
        <button
          onClick={() => {
            setIsEditing(false);
            // 取消时清空编辑状态值,下次编辑会重新赋值最新title
            setEditedTitle('');
          }}
        >
          Cancel
        </button>
        <button
          onClick={() => {
            setIsEditing(false);
            onSaveTodo(id, editedTitle);
          }}
        >
          Save
        </button>
      </>
    );
  } else {
    todoContent = (
      <>
        <label>{title}</label>{" "}
        <button onClick={() => {
          setIsEditing(true);
          // 进入编辑状态时,才从props获取最新的title
          setEditedTitle(title);
        }}>
          Edit
        </button>
      </>
    );
  }

  return (
    <li>
      <input
        type="checkbox"
        checked={done}
        onChange={(e) => onDoneTodo(id, e.target.checked)}
      />{" "}
      {todoContent}
      <button onClick={() => onDeleteTodo(id)}>Delete</button>
    </li>
  );
}

关键修改点

  1. 初始化状态调整:editedTitle初始值设为空字符串,不再依赖title props,避免了初始state依赖props的反模式。
  2. 编辑时赋值:当用户点击「Edit」按钮进入编辑状态时,才将当前最新的title props赋值给editedTitle,确保编辑的是最新数据。
  3. 移除无用属性:去掉了input的defaultValue,因为使用value={editedTitle}已经是受控组件,defaultValue不再需要。

额外优化(可选)

如果需要在非编辑状态下,当父组件的title更新时,确保editedTitle同步最新值(虽然非编辑状态下不会显示这个值),可以添加useEffect监听:

import { useEffect } from 'react';

// ... 组件内部
useEffect(() => {
  // 只有非编辑状态下,才同步props的title到editedTitle
  if (!isEditing) {
    setEditedTitle(title);
  }
}, [title, isEditing]);

不过实际上,点击Edit按钮时直接赋值title已经能保证拿到最新值,所以这个useEffect并非必须。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:58:10