Массивы объектов в стейтах React

В прошлых статьях были разобраны примеры реактивного поведения массивов и объектов. Теперь попробуем совместить все знания, чтобы понять как обычно в React используются массивы объектов. Для работы с подобными данными обычно используется дополнительное свойство "id", по которому можно найти нужный объект внутри массива. При таком подходе для поиска нужного объекта приходится перебирать их все внутри массива. Отсюда возникают различные сложности.

Предположим, что существует массив объектов. Для вывода каждого элемента массива нужно перебрать каждый объект и все их свойства. Приведём пример упрощённого кода для вывода. При этом запишем сам массив в стейт, чтобы срабатывала реактивность:
const mouseText = [
   {
      id: 'tl2zI5J3IbLwukybTEsIxXXb6',
      prop1: 'Тише',
      prop2: 'мыши',
      prop3: 'кот',
      prop4: 'на крыше',
   },
   {
      id: 'ViWgVtvU2qRo6huLg18DdYuio',
      prop1: 'А',
      prop2: 'котята',
      prop3: 'ещё',
      prop4: 'выше',
   },
   {
      id: 'wEp5mHF4StNNoo29JVxFZxcOq',
      prop1: 'Кот',
      prop2: 'пошёл',
      prop3: 'за',
      prop4: 'молоком',
   },
];

import React, { useState } from 'react';

function App() {
   const [objArr, setValue] = useState(mouseText);
   
   const result = objArr.map((obj) => {
      return <p key={obj.id}>
         {obj.prop1} {obj.prop2} {obj.prop3} {obj.prop4}
      </p>;
   });

   return <div>
      {result}
   </div>;
}

export default App;
Теперь попробуем произвести базовые действия над этим массивов объектов. Такие так удаление, добавление, изменение и получение значения свойства. Все эти действия будут производится над копиями массива объектов, как и в случае с простыми массивами и объектами. Поэтому будем активно использовать функцию "setValue" нашего примера, которая отвечает за перезапись стейта.

Добавление объекта в массив

Пример кода для добавления объекта в такой массив:
const add = {
   id: '38GlFQnHM10UuRDNVUdiebjTq',
   prop1: 'А',
   prop2: 'котята',
   prop3: 'кувырком',
};
let copy = Object.assign([], objArr);
copy.push(add);
setValue(copy);
Метод "Object.assign" используется для копирования значений всех свойств из одного объекта (во втором параметре) другой (в первом параметре).

Код из примера можно сократить, используя деструктуризацию. Результат выполнения будет аналогичен результату из предыдущего примера:
const add = { // добавляемый объект
   id: '38GlFQnHM10UuRDNVUdiebjTq',
   prop1: 'А',
   prop2: 'котята',
   prop3: 'кувырком',
};
setValue([...objArr, add]);

Удаление

Для удаления объекта из массива необходимо сначала найти его. То есть нажно перебрать весь массив, все объекта, и найти тот "id", который просят удалить. Всё это действие можно упаковать внутрь одной стрелочной функции, которую можно вызывать внутри метода filter при сохранении стейта. То есть можно сделать так:
setValue(objArr.filter(obj => {
   if (obj.id != '38GlFQnHM10UuRDNVUdiebjTq') {
      return obj;
   }
}));
- в этом примере мы пытаемся удалить элемент с id равным "38GlF....bjTq".

Можно упростить этот код примера до такого:
setValue(objArr.filter(obj => obj.id != '38GlFQnHM10UuRDNVUdiebjTq'));

Изменение

Изменение свойства объекта тоже происходит по определённому "id", который ещё надо найти в массиве объектов. Попробуем заменить один объект на другой при успешном нахождении:
const change = {
   id: 'ViWgVtvU2qRo6huLg18DdYuio',
   prop1: 'А',
   prop2: 'котята',
   prop3: 'кувырком',
};
setValue(objArr.map(obj => {
   if (obj.id == change.id) { // объект найден
      return change; // делаем замену
   } else { // объект не найде
      return obj; // возвращаем старый объект
   }
}));
Этот код можно сократить до такого:
const change = {
   id: 'ViWgVtvU2qRo6huLg18DdYuio',
   prop1: 'А',
   prop2: 'котята',
   prop3: 'кувырком',
};
setValue(objArr.map(obj => obj.id == change.id ? change : obj));
Иногда нужно изменить не весь объект, а только одно свойство. Предположим, что надо заменить значение свойства "prop2" на "Сыр" у объекта с id равным "tl2zI....Xb6". Тогда напишем такой код:
const id = 'tl2zI5J3IbLwukybTEsIxXXb6';
const prop = 'prop2';
const value = 'Сыр';
setValue(objArr.map(obj => {
   if (obj.id == id) {
      return {...obj, [prop]: value};
   } else {
      return obj;
   }
}));

Получение объекта или его свойства

Для получения одного объекта внутри массива можно использовать метод "reduce". Этот метод может выполнять функцию над всеми элементами массива и выдавать общий результат. Передаваемая ему функция должна возвращать значение промежуточного результата. К примеру, это удобно для подсчёта суммы элементов массива. У метода есть 4 параметра:
  1. содержит промежуточный результат;
  2. содержит текущий элемент массива;
  3. содержит текущий индекс элемента, над которым выполняется действие;
  4. содержит сам массив.
Попробуем использовать этот метод для получения объекта с id равным "tl2zI....Xb6":
const id = 'tl2zI5J3IbLwukybTEsIxXXb6';
const result = objArr.reduce((res, obj) => {
   if (obj.id == id) {
      return obj;
   } else {
      return res;
   }
}, {});
Такой код можно записать в компактном виде:
const id = 'tl2zI5J3IbLwukybTEsIxXXb6';
const result = objArr.reduce((res, obj) => obj.id == id ? obj : res, {}); 
Если же нужно получить только свойство объекта, например "prop2", то получится такой код:
const id = 'tl2zI5J3IbLwukybTEsIxXXb6';
const prop = 'prop2';
const result = objArr.reduce((res, obj) => {
   if (obj.id == id) {
      return obj[prop]; // возвращаем только одно значение
   } else {
      return res;
   }
}, '');
Этот код можно сократить до:
const id = 'tl2zI5J3IbLwukybTEsIxXXb6';
const prop = 'prop2';
const result = objArr.reduce((res, obj) => obj.id == id ? obj[prop] : res, ''); 
MouseDC.ru - хостинг, виртуальный хостинг, покупка доменов, проверка доменов, WHOIS, курсы создания сайтов, вебинары по созданию, курсы разработки сайтов, доработка сайтов, сопровождение сайтов, разработка сайтов, техподдержка сайтов
Cмотрите другие статьи:
Была ли статья полезной?
Была ли эта статья полезна? Есть вопрос?
хостинг для сайтов
Закажите недорогой хостинг Заказать

всего от 290 руб

⇡ наверх