我正在尝试学习新的React钩子。我编写了一个简单的待办事项列表,用户可以输入输入以创建新的待办事项,然后单击待办事项以将其删除。但是,在删除待办事项后,它不会重新渲染。
这是我的代码
import React, { useState, Fragment } from "react";
const Todo = () => {
const [inputVal, setInput] = useState("");
const [list, setList] = useState([]);
const handleInput = e => {
setInput(e.target.value);
};
const handleClick = () => {
setList([...list, inputVal]);
setInput("");
};
const handleDelete = index => {
setList([...list.splice(index, 1)]);
console.log(list);
};
const renderList = () =>
list.map((item, index) => {
return (
<div key={index} onClick={() => handleDelete(index)}>
{item}
</div>
);
});
return (
<Fragment>
<div>
<input value={inputVal} onChange={handleInput} />
<button onClick={handleClick}>submit</button>
</div>
<ul>{renderList()}</ul>
</Fragment>
);
};
export default Todo;
答案 0 :(得分:1)
您在这里有两个问题。
array.splice
正在变异并返回删除的项目。
当您运行setList([...list.splice(index, 1)]);
这将从对象list
中删除一项,然后调用setList([removed_item])
。
您可以将这一行替换为
setList(list.slice(0, index).concat(list.slice(index + 1))
当前正在发生的事情是,您将状态设置为与以前相同(但已突变)的对象,因此不会触发重新渲染。
key
属性。您可以阅读文档here 如果项的顺序可能更改,我们不建议使用索引作为键。这可能会对性能产生负面影响,并可能导致组件状态出现问题。
您的键应唯一地标识待办事项列表的元素,而无需引用列表本身。该项目中的文本是一个不错的选择,但可能存在非唯一性的问题。
当您重新渲染待办事项列表时,React使用按键来决定要重新渲染哪些子代。如果使用索引作为键,然后删除索引0处的项目,则不会告知第0个子元素更新为新的第0个元素,因为它仍然获得相同的键。