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> ); }
关键修改点
- 初始化状态调整:
editedTitle初始值设为空字符串,不再依赖titleprops,避免了初始state依赖props的反模式。 - 编辑时赋值:当用户点击「Edit」按钮进入编辑状态时,才将当前最新的
titleprops赋值给editedTitle,确保编辑的是最新数据。 - 移除无用属性:去掉了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
相关产品推荐
相关产品推荐

