#reactjs
#reactjs
Вопрос:
Я пытаюсь создать список дел, из которого я удаляю элементы и меняю их статус на завершено. Когда я нажимаю флажок элемента, он удаляет только первый элемент, а когда я пытаюсь изменить статус элемента на завершено, он сообщает, что этот элемент не существует. Поэтому я предполагаю, что это проблема с индексом элемента, который я передаю в функцию удаления. Буду признателен за любую помощь, спасибо.
Это объекты todo:
const [todos, setTodos] = useState([
{
text: "Learn about React",
isCompleted: true
},
{
text: "Meet friend for lunch",
isCompleted: false
},
{
text: "Wash Dishes",
isCompleted: false
}
]);
Это то, что вызывается, когда я удаляю элемент
const removeTodo = index => {
const checkTodos = [...todos]; //The list is copied and isCompleted is changed to true
checkTodos[index].isCompleted = true; //This line results in:
setTodos(checkTodos); //Cannot set property 'isCompleted' of undefined
const newTodos = [...todos]; //Here is where I remove from the list
newTodos.splice(index, 1); //I remove the specific index but it deletes only the first
setTodos(newTodos); //item no matter where I click
};
Вот как я вызываю функцию удаления
<div style = {{paddingTop: 40}}>
<List>
{todos.map((value) => {
return(
<ListItem>
<ListItemIcon>
<Checkbox
edge="start"
checked={value.isCompleted}
onChange={removeTodo} //Remove function is called here
tabIndex={-1}
disableRipple
/>
</ListItemIcon>
<ListItemText disableTypography style={{fontFamily: 'Work Sans', fontSize: 35}} primary={value.text}/>
</ListItem>
);
})}
</List>
</div>
Комментарии:
1. Во-первых, вы фактически не передаете индекс
removeTodo
функции, так как же она узнает, на какую из них вы ссылаетесь? Кроме того, если вы имеете дело с динамическим списком (добавление / удаление элементов), вы не можете использовать индекс в качестве идентификатора. Им нужно что-то уникальное2. @pilchard: разве это не должно быть
onChange={() => removeTodo(index)}
?3. да, но, увы, слишком поздно его редактировать.
4. Я согласен с Jayce444 в том, что вы должны использовать какой-то уникальный идентификатор для ссылки на todos, но чтобы получить то, что у вас работает, попробуйте передать index из map в onChange…
{todos.map((value, index) => { ... <Checkbox onChange={() => removeTodo(index)}>...}
5. вы добавили индекс к переданным аргументам из
map()
?{todos.map((value, index) =>
Ответ №1:
В react, если вы используете Map, вы должны предоставить ключ своим дочерним элементам, чтобы он мог однозначно идентифицировать все. Затем вызовите removeTodo с индексом, чтобы удалить его должным образом.
<div style = {{paddingTop: 40}}>
<List>
{todos.map((value, index) => {
return(
<ListItem key={value}>
<ListItemIcon>
<Checkbox
edge="start"
checked={value.isCompleted}
onChange={() => removeTodo(index)}
tabIndex={-1}
disableRipple
/>
</ListItemIcon>
<ListItemText disableTypography style={{fontFamily: 'Work Sans', fontSize: 35}} primary={value.text}/>
</ListItem>
);
})}
</List>
</div>