Я пытаюсь удалить (полу) глубоко вложенный элемент из массива с помощью setState, но, похоже, он не работает. Мое состояние устроено следующим образом:
state = {
currentSeries: null,
currentRowIndex: null,
rows: [
{
id: shortid.generate(),
nodes: [],
series: [], // array with item I want to remove
},
],
};
и мой вызов удаления элемента:
onRemoveModelElementClick = (rowId, modelElementId) => {
this.setState((prevState) => {
const index = prevState.rows.findIndex(x => x.id === rowId);
const series = prevState.rows[index].series.filter(s => s.id !== modelElementId);
return series;
});
};
Я пытался распространить оставшееся состояние несколькими способами, но, похоже, оно не обновляется должным образом. I rowId и modelElementId верны, и я могу убедиться, что они отфильтровывают правильный элемент. У меня просто проблемы с тем, что вернуть. Я знаю, что это что-то простое, но хоть убей, я не могу этого понять.
Я бы порекомендовал использовать .map
, чтобы упростить восприятие. Затем вы можете написать это так:
onRemoveModelElementClick = (rowId, modelElementId) => {
const updatedRowsState = this.state.rows.map(row => {
// this is not the row you're looking for so return the original row
if (row.id !== rowId) {
return row;
}
const filteredSeries = row.series.filter(s => s.id !== modelElementId);
return {
// spread properties (id, node, series)
...row,
// overwrite series with item filtered out
series: filteredSeries,
};
});
// since rest of the state doesn't change, we only need to update rows property
this.setState('rows', updatedRowsState);
}
Надеюсь, это поможет, и дайте мне знать, если у вас есть какие-либо вопросы.
Я думаю, проблема здесь в том, как ваш код использует setState
. Функция setState
должна возвращать объект. Предполагая, что ваши функции фильтрации верны, как вы описываете, верните объект для обновления состояния:
return { series };
Вот что я сделал, чтобы заставить его работать, если это может помочь кому-то еще:
onRemoveModelElementClick = (rowId, modelElementId) => {
this.setState((prevState) => {
const updatedRowState = prevState.rows.map((row) => {
if (row.id !== rowId) {
return row;
}
const filteredSeries = row.series.filter(s => s.id !== modelElementId);
return {
...row,
series: filteredSeries,
};
});
return {
rows: updatedRowState,
};
});
};
Спасибо Дому за прекрасную идею и логику!
Это отличная идея. То, что вы написали, не работает из коробки, но это дало мне решение, поэтому я принимаю его. Я также добавлю ответ о том, что я сделал, чтобы заставить его работать.