我一直在尝试使用React Hooks制作Todo List应用程序。
当我使用<span>{todo}</span>
时,一切都很好。它只是删除了我单击的元素。但是,当我将<span>{todo}</span>
更改为<input></input>
时,我单击要删除的每个"X"都会删除最后一个元素。我只是不知道发生了什么,因为钥匙没有换。
Todo.js组件:
import React, { useState } from 'react';
const TodoForm = ({ saveTodo }) => {
const[value, setValue] = useState('');
return (
<form
onSubmit={event => {
event.preventDefault();
saveTodo(value);
setValue('');
}}
>
<input onChange={event => setValue(event.target.value)} value={value} />
</form>
)
}
const TodoList =({ todos, deleteTodo }) => (
<ul>
{
todos.map((todo, index) => (
<li key={index.toString()}>
<span>{todo}</span>
<button onClick={() => deleteTodo(index)}>X</button>
</li>
))
}
</ul>
);
const Todo = () => {
const [todos, setTodos] = useState([]);
return (
<div className="App">
<h1>Todos</h1>
<TodoForm saveTodo={todoText => {
const trimmedText = todoText.trim();
if(trimmedText.length > 0) {
setTodos([...todos, trimmedText]);
}
}}
/>
<TodoList
todos={todos}
deleteTodo={todoIndex => {
const newTodos = todos.filter((_, index) => index !== todoIndex);
setTodos(newTodos);
}}
/>
</div>
);
};
export default Todo;
当我更改时,它会更改删除行为:
<li key={index.toString()}>
<span>{todo}</span>
<button onClick={() => deleteTodo(index)}>X</button>
</li>
至:
<li key={index.toString()}>
<input></input>
<button onClick={() => deleteTodo(index)}>X</button>
</li>
你确定是这样吗?或者它似乎只是这样表现,因为您在没有任何值的情况下渲染输入?如果我将代码粘贴到CodeSandbox中(并调整输入以实际包含todo的值(,它会删除正确的元素。还请考虑使用索引作为列表键应该被视为"最后的手段"(请参阅React文档(。
问题是使用index
作为密钥。因此,最后一个项目(停止存在的key
(被删除,并且所有其他项目都被更新。
相反,为您的todo创建某种独特的id
,并将该id
用作key
。