Форма добавления, удаления и изменения элементов на стейтах React

В этой статье будет приведён пример создания интерактивной формы в React, через которую можно добавлять элементы. В коде будет использоваться информация о реактивности массивов и изменения input полей, которую можно найти в предыдущих статьях этого курса:

Добавление элементов

Попробуем сделать интерактивную форму, через которую пользователь может добавлять произвольные текстовые элементы. Над формой будет отображаться список существующих элементов, а под ней поле для ввода нового и кнопка для сохранения.

Сначала распишем всё подробно, не сокращая до стрелочных функций:
import React, { useState } from 'react';

function App() {
   const [arr, setArr] = useState(['Тише', 'мыши', 'кот', 'на', 'крыше']);
   const [value, setValue] = useState('');
   
   const result = arr.map((element, index) => {
      return <p key={index}>{element}</p>;
   });

   function add() {
      setArr([...arr, value]);
   }

   function inputValue(event) {
      setValue(event.target.value);
   }

   return <div>
      {result}
      <input value={value} onChange={inputValue} />
      <input onClick={add}>Добавить элемент</div>
   </div>;
}

export default App;
Теперь перепишем в сокращённом виде, используя стрелочные функции. Так будет легче воспринимать код, потому что в функциях "add" и "inputValue" содержится всего по одному действию:
import React, { useState } from 'react';

function App() {
   const [arr, setArr] = useState(['Тише', 'мыши', 'кот', 'на', 'крыше']);
   const [value, setValue] = useState('');
   
   const result = arr.map((element, index) => {
      return <p key={index}>{element}</p>;
   });

   return <div>
      {result}
      <input value={value} onChange={event => setValue(event.target.value)} />
      <input onClick={event => setArr([...arr, value])}>Добавить элемент</div>
   </div>;
}

export default App;

Удаление элементов

Часто в реальных проектах встречаются формы, в которые можно не только добавлять свои данные, но и удалять их. К сожалению, наш пример не содержит функционала удаления элемента. Давайте это исправим.

Для упрощения примера не будем делать отдельную красивую кнопку удаления элементов. Сделаем функцию их удаления через клик по строке.

С перерисовкой списка нам поможет реактивность React. Остаётся только верно запрограммировать удаление элемента массива. Для этого создадим функцию "remove", которой будет передаваться номер элемента массива, который надо удалить. Этот номер будет передаваться функции во время двойного клика по строке, которую надо удалить через атрибут события onDoubleClick. Напишем этот код:
import React, { useState } from 'react';

function App() {
   const [arr, setArr] = useState(['Тише', 'мыши', 'кот', 'на', 'крыше']);
   const [value, setValue] = useState('');
   
   const result = arr.map((element, index) => {
      return <p key={index} onDoubleClick="{() => remove(index)}">
         {element}
      </p>;
   });

   function remove(index) {
      setArr([...arr.slice(0, index), ...arr.slice(index + 1)]);
   }

   return <div>
      {result}
      <input value={value} onChange={event => setValue(event.target.value)} />
      <input onClick={event => setArr([...arr, value])}>Добавить элемент</div>
   </div>;
}

export default App;

Изменение элементов

Разовьём развить логику нашего примера ещё дальше, добавив изменение элемента по одинарному клику на строку. То есть если кликнуть по элементу, то текст из него будет появляться в input поле под формой. А окончание изменённого текста всё так же будет производиться с помощью кнопки.

Чтобы в любой момент можно было понять, что пользователь находится в режиме редактирования элемента, необходимо добавить ещё один стейт. В нём будет храниться номер элемента, который редактируется, или null значение, если ничего не редактируется в текущий момент. Номер будет попадать в стейт при одиночном клике по полю onClick (двойной клик onDoubleClick уже зарезервирован для удаления элемента)

Для простоты объяснения будем использова два набора полей полей ввода и две кнопки. Один набор будет отображаться при вызове режима редактирования, а второй только для добавления. Напишем код:
import React, { useState } from 'react';

function App() {
   const [arr, setArr] = useState(['Тише', 'мыши', 'кот', 'на', 'крыше']);
   const [value, setValue] = useState('');
   const [editIndex, setEditIndex] = useState(null);
   
   const result = arr.map((element, index) => {
      return <p key={index}
         onClick="{() => edit(index)}"
         onDoubleClick="{() => remove(index)}"
         >
         {element}
      </p>;
   });

   function edit(index) { // редактирование элемента
      setArr(
         [
            ...arr.slice(0, editIndex), 
            event.target.value,
            ...arr.slice(editIndex + 1)
         ]
      ); 
   }

   function stopEdit() { // завершение редактирования
      setEditIndex(null);
   }

   function remove(index) {
      setArr([...arr.slice(0, index), ...arr.slice(index + 1)]);
   }

   function add() { // добавление элемента
      setArr([...arr, value]);
   }

   function changeValue(event) { // изменение содержания поля input
      setValue(event.target.value);
   }
 
   let fields; // поле и кнопка
   if (editIndex){ // для редактирования элемента
      fields = <div>
         <input value={arr[editIndex]} onChange={edit} />
         <input onClick={stopEdit}>Изменить элемент</div>
      </div>;
   }else{ // для добавления нового элемента
      fields = <div>
         <input value={value} onChange={changeValue} />
         <input onClick={add)}>Добавить элемент</div>
      </div>;
   }

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

export default App;
MouseDC.ru - хостинг, виртуальный хостинг, покупка доменов, проверка доменов, WHOIS, курсы создания сайтов, вебинары по созданию, курсы разработки сайтов, доработка сайтов, сопровождение сайтов, разработка сайтов, техподдержка сайтов
Cмотрите другие статьи:
Была ли статья полезной?
Была ли эта статья полезна? Есть вопрос?
хостинг для сайтов
Закажите недорогой хостинг Заказать

всего от 290 руб

⇡ наверх