#javascript #reactjs
#javascript #reactjs
Вопрос:
по сути, у меня есть приложение на базе KanbanBoard, которое я пытаюсь разработать, и я получаю какое-то странное поведение, когда я вызываю свою функцию удаления из моей функции проверки. Код находится здесь, в codesandbox. Основная проблема заключается в том, что при наличии нескольких карточек, и я пытаюсь удалить card
с помощью события onBlur, карточка, на которой происходит событие, не удаляется, но удаляется другая пустая карточка. Это работает должным образом, если все остальные карточки в столбце содержат текст. Пожалуйста, игнорируйте код dnd, поскольку он появился после первоначальной проблемы.
Заранее спасибо.
РЕДАКТИРОВАТЬ: Вот логика с App.js
state = { list: list }
handleChange = (e, col) => {
let eid = parseInt(e.target.id)
let updatedList = this.state.list.map(obj => {
if (obj.id === col) {
let card = { text: e.target.value }
obj.cards[eid] = card
}
return obj
})
this.setState({ list: updatedList })
}
setText = (e, col) => {
if (e.target.value === "") {
e.target.placeholder = "YOU MUST ENTER TEXT. THIS BOX WILL CLOSE NOW"
e.persist()
setTimeout(() => {
this.delete(e, col)
}, 3000)
return
}
}
delete = (e, col) => {
e.preventDefault()
let eid = parseInt(e.target.id)
let updatedList = this.state.list.map(obj => {
if (obj.id === col) {
obj.cards = obj.cards.filter((c,i) => i !== eid)
//obj.counter--
}
return obj
})
this.setState({ list: updatedList })
}
add = e => {
e.preventDefault()
let eid = parseInt(e.target.id)
let updatedList = this.state.list.map(obj => {
if (obj.id === eid) {
let card = {text:""}
obj.cards.push(card)
obj.counter
}
return obj
})
this.setState({ list: updatedList })
}
}
Ответ №1:
map
возвращает элемент для каждого элемента, через который выполняется итерация. Возможно, использование filter
помогло бы в этом случае. Я предполагаю, что ваш splice
порядок this.state.list
становится сумасшедшим и запутанным.
let updatedList = this.state.list.filter(obj => obj.id !== col);
Не уверен, что col
или eid
является правильным для сравнения, но это даст вам новый список со всеми предыдущими элементами, за исключением того, чей идентификатор совпадает с идентификатором, который вы пытаетесь удалить.
Взглянув на ваш codesandbox, есть некоторые проблемы. Чтобы довести это до высокого уровня — у каждой карты должен быть неизменяемый идентификатор, который вы можете использовать для ее удаления. Вы используете индекс карточки в массиве и объединяете его неизвестно с чем еще. Вы потеряли свой источник истины, что особенно важно, когда вы разрешаете пользователю изменять порядок массива. Ваша карта должна запустить функцию удаления, которую вы передаете ей от ее родителя. Он должен просто взять идентификатор этой карты, отфильтровать его из текущего состояния и установить новое состояние. Вы делаете это слишком сложным.
Родительский —
state = { list : [{id: 1, ...other card stuff}, {...more cards}] };
delete = id => {
const newList = this.state.list.filter(item => item.id !== id);
this.setState({ list: newList };
}
render = () => {
const { list } = this.state;
return list.map(item => (
<Card
{...item}
onDelete={this.delete}
/>
))
}
Карточка —
// whenever you need to delete this card
this.props.onDelete(this.id);
Комментарии:
1. проблема не в
column
значении, а в том, что obj.cards обновляется правильно, но удаляется неправильный. Проверьте мой App.js в Codesandbox.2. Лучше не ссылаться на другие страницы в StackOverflow. Если эти ссылки в будущем прервутся, любые комментарии или ответы, ссылающиеся на них здесь, будут представлены (каламбур не предназначен) запутанными или бесполезными. Разместите соответствующие части вашего кода здесь, пожалуйста.
3. Я прочитал ваш пост и понимаю, что мне нужно сделать, изменив структуру моего списка и сохранив неизменным мое состояние, я даже не рассматривал, что взаимодействие с пользователем может быть источником ошибки. Большое спасибо, я многому научился из того, что вы написали… но это не решило проблему.