Форма изменения объекта в массиве в стейтах React

В предыдущих статьях были рассмотрены примеры кода для добавления и удаления объектов из массивов: В этой статье продолжим работать с объектами внутри массивов и рассмотрим пример кода для их изменения.

Для начала возьмём заготовку из предыдущих статей и внесём небольшое изменение. Добавим три поля для вывода свойств объекта. В этих полях можно будет редактировать свойства. А под полями ввода будет кнопка для сохранения изменений.

Выбор нужного объекта для изменения его свойств будет происходить по клику на кнопку в нужной строке с выводом свойств объекта. При этом в отдельный стейт будет сохраняться сохраняться id элемента, который сейчас редактируется. А если в текйщий момент никакой объект не редактируется, то в этот стейт будет записано "null" значение.

Попробуем написать такой код:
const mouseText = [
   {
      id: 'tl2zI5J3IbLwukybTEsIxXXb6',
      prop1: 'Тише',
      prop2: 'мыши',
      prop3: 'кот на крыше',
   },
   {
      id: 'ViWgVtvU2qRo6huLg18DdYuio',
      prop1: 'А котята',
      prop2: 'ещё',
      prop3: 'выше',
   },
];

import React, { useState } from 'react';

function App() {
   const [objArr, setValue] = useState(mouseText);
   const [idToEdit, setIdToEdit] = useState(null); // id объекта, который сейчас редактируется
 
   function getValue(prop, event) { // получение значения свойства
      return objArr.reduce((res, obj) => {
         if (obj.id == idToEdit) {
            return obj[prop];
         } else {
            return res;
         },
      }, '');
   }

   function change(prop, event) { // изменение input поля
      setValue(objArr.map(obj => {
         if (obj.id == idToEdit) {
            return {...obj, [prop]: event.target.value};
         } else {
            return obj;
         }
      }));
   }
   
   const result = objArr.map((obj) => {
      return <p key={obj.id}>
         {obj.prop1}
         {obj.prop2}
         {obj.prop3}

         <button onClick={() => setIdToEdit(obj.id)}>Изменить</button>
      </p>;
   });

   return <div>
      {result}

      <br /> 
      <input value={getValue('prop1')} onChange={event => change('prop1', event)} /> 
      <input value={getValue('prop2')} onChange={event => change('prop2', event)} /> 
      <input value={getValue('prop3')} onChange={event => change('prop3', event)} /> 
      
      <br /> 
      <button onClick={setIdToEdit(null)}>Сохранить изменения</button>
   </div>;
}

export default App;
Код функций плучился громоздким. Попробуем сократить его. Получится так:
function App() {
   const [objArr, setValue] = useState(mouseText);
   const [idToEdit, setIdToEdit] = useState(null); // id объекта, который сейчас редактируется
 
   function getValue(prop, event) { // получение значения свойства
      return objArr.reduce(
         (res, obj) => obj.id == idToEdit ? obj[prop] : res
      , ''); 
   }

   function change(prop, event) { // изменение input поля
      setValue(objArr.map(obj =>
         obj.id == idToEdit ? {...obj, [prop]: event.target.value} : obj 
      ));
   }
   
   const result = objArr.map((obj) => {
      return <p key={obj.id}>
         {obj.prop1}
         {obj.prop2}
         {obj.prop3}

         <button onClick={() => setIdToEdit(obj.id)}>Изменить</button>
      </p>;
   });

   return <div>
      {result}

      <br /> 
      <input value={getValue('prop1')} onChange={event => change('prop1', event)} /> 
      <input value={getValue('prop2')} onChange={event => change('prop2', event)} /> 
      <input value={getValue('prop3')} onChange={event => change('prop3', event)} /> 
      
      <br /> 
      <button onClick={setIdToEdit(null)}>Сохранить изменения</button>
   </div>;
}
MouseDC.ru - хостинг, виртуальный хостинг, покупка доменов, проверка доменов, WHOIS, курсы создания сайтов, вебинары по созданию, курсы разработки сайтов, доработка сайтов, сопровождение сайтов, разработка сайтов, техподдержка сайтов
Cмотрите другие статьи:
Была ли статья полезной?
Была ли эта статья полезна? Есть вопрос?
хостинг для сайтов
Закажите недорогой хостинг Заказать

всего от 290 руб

⇡ наверх