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内部的列表优化。
解决办法(二选一即可):
- 去掉外层冗余的
<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} /> ));
- 保留外层
<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无法删除任务
结合之前的问题,这里有两个核心错误:
- 原来的任务对象中
id是包装后的对象,你在Task组件里传递的是this.props.id.keyid,但在handleRemove里过滤时用了n.keyid !== keyid——而任务对象里根本没有keyid这个属性,只有id.keyid,所以过滤条件永远不成立,任务不会被删掉。 - 等你把问题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
相关产品推荐
相关产品推荐

