如何通过window.prompt获取标识实现React Todo的handleDelete删除功能?
解决方案:给待办项加唯一ID实现删除,无需替换window.prompt
不用替换window.prompt,只要给每个待办任务添加唯一标识(ID),就能精准定位要删除的项,代码改动极小,完全符合你“少代码”的需求。
1. 扩展Todo类型,添加ID字段
修改你的ITodo接口,新增id字段用于唯一标识任务:
interface ITodo { id: number; // 用数字类型的时间戳即可,无需额外依赖 taskName: string; }
2. 创建新任务时生成唯一ID
在handleClick中,用Date.now()生成时间戳作为ID(保证每次添加的任务ID唯一),同时处理用户取消输入的情况:
const handleClick = () => { const promptResult = window.prompt('Enter name of new task'); if (!promptResult) return; // 用户点取消时不添加空任务 const newTask: ITodo = { id: Date.now(), taskName: promptResult, }; setTask([...task, newTask]); };
3. 实现删除逻辑
让handleDelete接收要删除的任务ID,通过过滤数组移除对应项:
const handleDelete = (taskId: number) => { setTask(prevTasks => prevTasks.filter(task => task.id !== taskId)); };
4. 渲染时传递ID并设置React列表Key
遍历任务时,把当前任务的ID传给删除按钮的点击事件,同时给Todo组件添加key(React列表渲染的必填项):
{task.map(({ id, taskName }) => { return ( <Todo key={id}> <TaskTitle>{taskName}</TaskTitle> <DeleteButton onClick={() => handleDelete(id)}>Delete</DeleteButton> </Todo> ); })}
额外说明
- 用ID删除是最可靠的方案,哪怕存在同名任务也不会删错;如果强行用任务名删除,遇到重复任务会批量删除,不推荐。
- 如果你只是做简单演示,
window.prompt完全够用;但如果是正式项目,还是建议替换为真实输入框——毕竟prompt样式无法自定义,也没法做输入校验(比如禁止空任务),用户体验较差。但按你“少代码”的需求,上述方案完全满足。
完整修改后的代码:
import * as React from 'react'; import styled from 'styled-components'; const Container = styled.div``; const Todo = styled.div` display: flex; align-items: center; `; const TaskTitle = styled.p` margin-right: 8px; `; const DeleteButton = styled.button``; interface ITodo { id: number; taskName: string; } export default function App() { const [task, setTask] = React.useState<ITodo[]>([]); const handleDelete = (taskId: number) => { setTask(prevTasks => prevTasks.filter(task => task.id !== taskId)); }; const handleClick = () => { const promptResult = window.prompt('Enter name of new task'); if (!promptResult) return; const newTask: ITodo = { id: Date.now(), taskName: promptResult, }; setTask([...task, newTask]); }; return ( <Container> <button onClick={handleClick}>+</button> {task.map(({ id, taskName }) => { return ( <Todo key={id}> <TaskTitle>{taskName}</TaskTitle> <DeleteButton onClick={() => handleDelete(id)}>Delete</DeleteButton> </Todo> ); })} </Container> ); }
内容的提问来源于stack exchange,提问作者Aloske
相关产品推荐
相关产品推荐

