React状态对象更新问题:Todo应用完成按钮功能实现
解决Todo项状态更新问题
要实现点击「Completed」按钮将对应Todo的status从false改为true,只需调整按钮点击事件绑定并编写对应的状态更新逻辑,具体操作如下:
1. 给按钮点击事件传递目标Todo标识
在渲染Todo列表的map循环中,给按钮的onClick传递当前Todo的文本(作为临时标识):
const showText = todos.map((txt) => ( <li key={txt.text} className={!txt.status ? "" : "dark"}> <span>{txt.text}</span> <button onClick={() => handleChange(txt.text)}>Completed</button> </li> ));
2. 编写handleChange函数实现状态更新
通过setTodos遍历原Todo列表,找到目标Todo后修改其status属性,其余项保持不变:
function handleChange(targetText) { setTodos(prevTodos => { return prevTodos.map(todo => { if (todo.text === targetText) { // 复制原todo对象并修改status为true return {...todo, status: true}; } return todo; }); }); }
可选优化:避免重复文本导致的渲染问题
当前用txt.text作为React元素的key,如果添加相同文本的Todo会引发渲染异常,建议给每个Todo添加唯一ID:
- 添加Todo时生成唯一ID:
function handleAdd() { setTodos((prevState) => { return [...prevState, { id: Date.now(), // 用时间戳生成临时唯一ID text: todosText, status: false }]; }); }
- 渲染时用
id作为key并传递给handleChange:
const showText = todos.map((todo) => ( <li key={todo.id} className={!todo.status ? "" : "dark"}> <span>{todo.text}</span> <button onClick={() => handleChange(todo.id)}>Completed</button> </li> ));
- 对应修改
handleChange函数:
function handleChange(targetId) { setTodos(prevTodos => { return prevTodos.map(todo => { if (todo.id === targetId) { return {...todo, status: true}; } return todo; }); }); }
内容的提问来源于stack exchange,提问作者G-guy
相关产品推荐
相关产品推荐

