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

React TodoList项目技术求助:uuid属性为何转为对象、key警告及任务删除功能失效

嘿,我来帮你拆解并解决这三个TodoList的问题:

问题1:Task组件中this.props.id输出对象而非字符串

这是你在创建任务对象时的小疏忽导致的!在TaskList.js的handleSubmit方法里,你写了:

let task2addWithID = { ...task2add, id: {keyid}, key: {keyid}};

这里的{keyid}是ES6对象字面量的简写,等价于{keyid: keyid}——也就是说你把生成的UUID字符串包装成了一个包含keyid属性的对象,所以传递给Task组件的id自然就是这个对象啦。

解决办法:把对象包装改成直接赋值字符串:

let task2addWithID = { ...task2add, id: keyid, key: keyid};

这样id和key就都是UUID字符串了,Task组件里console.log(this.props.id)就会输出预期的字符串值。

问题2:已设置key但仍收到React警告

React对key的要求是:map循环生成的列表中,直接子元素必须带有唯一的key属性。看你的代码:

let tasklist = this.state.todoArr.map(task => (
  <div>
    <Task taskTitle={task.title} taskText={task.text} key={task.key} id={task.id} ... />
  </div>
));

你把key加在了嵌套的<Task>组件上,但map的直接子元素是外层的<div>,这个<div>没有key——这就是警告的根源。另外要注意:React不会把组件上的key作为props传递给子组件,所以Task组件里拿不到this.props.key,这个属性只用于React内部的列表优化。

解决办法(二选一即可):

  1. 去掉外层冗余的<div>,直接把key加在<Task>上:
let tasklist = this.state.todoArr.map(task => (
  <Task 
    taskTitle={task.title} 
    taskText={task.text} 
    key={task.key} 
    id={task.id} 
    handleRemove={this.handleRemove} 
    handleEdit={this.handleEdit} 
  />
));
  1. 保留外层<div>,把key移到这个<div>上:
let tasklist = this.state.todoArr.map(task => (
  <div key={task.key}>
    <Task 
      taskTitle={task.title} 
      taskText={task.text} 
      id={task.id} 
      handleRemove={this.handleRemove} 
      handleEdit={this.handleEdit} 
    />
  </div>
));

问题3:调用handleRemove无法删除任务

结合之前的问题,这里有两个核心错误:

  1. 原来的任务对象中id是包装后的对象,你在Task组件里传递的是this.props.id.keyid,但在handleRemove里过滤时用了n.keyid !== keyid——而任务对象里根本没有keyid这个属性,只有id.keyid,所以过滤条件永远不成立,任务不会被删掉。
  2. 等你把问题1解决后,id变成了字符串,就需要同步修改过滤逻辑。

解决办法:
首先修改Task组件的handleRemove,直接传递字符串id:

handleRemove(evt){
  evt.preventDefault();
  console.log("MY ID MANNN");
  console.log(this.props.id);
  this.props.handleRemove(this.props.id); // 直接传递字符串id
  console.log("CALLED");
}

然后修改TaskList的handleRemove,用正确的属性过滤:

handleRemove(taskId){
  console.log("IN HANDLE REMOVE");
  console.log(taskId);
  this.setState(st => ({
    todoArr: st.todoArr.filter(task => task.id !== taskId )
  }));
}

这样就能正确匹配并删除对应id的任务了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 15:39:09