У меня есть массив объектов, у них нет точного распорядка и идентификации , но мне нужно найти объект с определенным id
и изменить в нем свойство crossout
.
Я это сделал так:
completeClick(e) {
const id = e.target.id;
let result = this.state.tasksArray.find(item => item.id == id);
result.span = true;
this.setState({ state: 1 });
}
Но из за того что я не могу изменить свойство напрямую(this.setState()
), я изменяю его через костыль result.span = true
. Как изменить код так , что бы я могу найти объект и изменить его напрямую через setState
?
Документация по React гласит (и я полностью с ней согласен):
Никогда не мутируйте this.state
напрямую, так как более поздний
вызов setState()
может перезаписать эту мутацию. Относитесь к
this.state
как к иммутабельному объекту.
Мутация состояния state приводит к непредвиденному поведению, так называемые сайд эффекты. Поэтому предлагаю Вам следующий способ изменения элемента массива из состояния:
completeClick(e) {
const id = e.target.id;
// ищем индекс элемента в массиве, удовлетворяющий условию поиска
const index = this.state.tasksArray.findIndex(item => item.id == id);
// если элемент был найден - выполним следующий код
if (index != -1) {
this.setState(prevState => ({
tasksArray: {
...prevState.tasksArray,
[prevState.tasksArray[index].span]: true,
},
}));
}
}
Такой подход гарантирует нам, что состояние не будет мутировать. Полезные ссылки:
Если данный подход выглядит громоздким или сложным, то можно попробовать сделать это через метод Object.assign
.
Метод Object.assign()
используется для копирования значений всех
собственных перечисляемых свойств из одного или более исходных
объектов в целевой объект. После копирования он возвращает целевой
объект.
В Вашем случае должно получиться как-то так:
completeClick(e) {
const id = e.target.id;
// клонирование исходного массив из state (можно и через spread syntax)
const tasks = Object.assign({}, this.state.tasksArray)
// ищем индекс элемента в массиве, удовлетворяющий условию поиска
const index = this.state.tasksArray.findIndex(item => item.id == id);
// если элемент был найден - выполним следующий код
if (index != -1) {
// меняем значение найденного элемента
tasks[index].span = true;
// присваиваем новое значение, без мутации
this.setState({ tasksArray: tasks });
}
}
Но есть обратная сторона медали, если объект имеет сложную вложенную структуру, метод Object.assign()
может начать работать не так, как хотелось бы. Для решения подобных вопросов можно воспользоваться готовым методом из lodash библиотеки: _.cloneDeep(value)
- этот метод рекурсивно клонирует значения.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Идея в том , что бы код считал сколько есть слов в массиве , которые заканчиваются "у" "іе"
Я в React JS новый, хотел бы кое что уточнить Код есть, в базе данных все корректно меняется при нажатии на кнопкуПроблема лишь в том, что оно не check-ается...