Пошаговое руководство по созданию простого компонента ввода тегов в React - в Интернете, вероятно, уже есть тысяча таких руководств, но мне пришлось сделать одно из них недавно для ... чего-то, чтобы вы выиграли / пострадали с еще одним из них в Интернете.

Ссылка на окончательное решение: https://codepen.io/jerrylow/pen/mvZZpp

Изменить. Я переместил <input> в список тегов, чтобы входные данные всегда оставались в соответствии со списком тегов, когда это возможно. На некоторых скриншотах это может не отражаться.

Редактировать 2: Начиная с React 16 хуки стали более широко использоваться, и писать повторно используемый код стало намного проще. Это руководство, написанное как функциональный компонент https://codepen.io/jerrylow/pen/RwWbgPx. Я не буду разбивать его построчно, так как большая часть кода и логики остались прежними. Я прокомментировал, где используется хук состояния.

Начиная

Я не собираюсь начинать с настройки вашего локального компьютера, создания приложения React и всего остального, я предполагаю, что вы уже настраивали React раньше, и мы собираемся начать с компонента. В этом примере я собираюсь визуализировать компонент прямо в ReactDOM:

То, что у меня есть, находится в одном файле:

В идеале у вас должен быть InputTag в собственном файле компонента, и он будет импортирован в часть вашего приложения:

Настройка DOM

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

Удаление комментариев и размещение их в компоненте:

На этом этапе вы можете сделать две вещи:

  1. Стилизуйте компонент, чтобы он выглядел лучше, или
  2. Добавьте функциональность, чтобы все работало.

Я визуальный человек, и обычно мне нравится сначала решать более простые задачи, поэтому на этом этапе я обычно стилизую компонент, но я знаю, что добавленная функциональность может повлиять на стили; таким образом, большинство разработчиков сначала откажутся от большей части функциональности - ради этой статьи я выберу этот путь - еще и потому, что я фактически не буду рассматривать стили в этой статье.

Заставьте поле ввода работать

Первая логическая функция, которую нужно решить, - это добавить теги из поля ввода. Мы будем хранить теги в состоянии компонента, поэтому мы установим состояние тега по умолчанию (пустой массив) в конструкторе.

Это будет в верхней части вашего компонента:

Если вы не знакомы с состоянием компонентов, ознакомьтесь с этим https://reactjs.org/docs/faq-state.html.

Чтобы добавить теги, я буду слушать, когда пользователь нажимает Enter, когда он сосредоточен на поле ввода. Для этого мы можем использовать либо добавить onKeyUp, либо onKeyDown в поле. Я буду использовать onKeyDown.

Теперь я вызываю функцию inputKeyDown, которую мы еще не написали - давайте приступим к работе.

Построчно с разбивкой

inputKeyDown = (e) => {

Создайте функцию с именем inputKeyDown, используя стрелочную функцию, чтобы она лексически привязала это к функции. Нам нужно сделать это только для доступа к this, поэтому вам не обязательно создавать всю свою функцию как функцию стрелки. Начиная с onKeyDown он передаст событие в качестве первого аргумента нашей функции, которую я только что назвал e.

const val = e.target.value;

Я назначаю входное значение val.

if (e.key === 'Enter' && val) {

Убедитесь, что нажатие клавиши действительно было Enter, и добавляйте тег только в том случае, если пользователь действительно ввел значение в поле.

this.setState({ tags: [...this.state.tags, val]});

Добавьте значение в состояние компонента tags с помощью this.setState(). Я назначаю тегам значение [...this.state.tags, val], это массив [], сначала расширяющий текущий список тегов, который уже находится в состоянии ...this.state.tags, а затем добавляю новый val в конце. Если бы мы просто присвоили тегам значение типа { tags: val }, мы бы перезаписали все теги одним значением.

Убедитесь, что это работает

На данный момент теги не выводятся, поэтому вы можете проверить, работает ли эта функция, console.log выведя this.state.tags, или вы можете использовать React Devtools для наблюдения за вашими реквизитами и состоянием (рекомендуется).

Очистка поля ввода

Как видно из вышеизложенного, после добавления тега значение остается в поле, что не идеально. Чтобы очистить поле, нам нужно установить для ввода значение null. Для этого нам нужно иметь возможность ссылаться на поле ввода, мы можем сделать это, ссылаясь на DOM. В поле ввода добавляем ref={c => { this.tagInput = c}}. Я называю этот ввод tagInput.

Теперь мы можем очистить значение после добавления в состояние.

Отображение тегов

Прежде чем мы добавим функцию удаления тегов, мы должны отобразить теги. Теперь мы можем заменить тег заполнителя <li> реальными тегами. Для этого мы будем использовать .map, чтобы перебирать теги и выводить их:

Каждый тег зациклен как tag. Я также добавляю индекс (i), который будет использоваться позже. Обратите внимание, что сейчас я использую тег в качестве ключа. Если вы не знаете, зачем вам нужны ключи, прочтите их, это отчасти то, что делает React потрясающим - не используйте индекс в качестве ключа. Теперь ключи должны быть уникальными, и использование тега в качестве ключа может вызвать ошибку дублирования, но это хорошо, поскольку нам также не нужны / не нужны дублированные теги - мы можем ограничить это. Мы добавим проверку, прежде чем теги будут переведены в состояние.

Теперь проверьте еще раз, и теги должны быть выведены:

Удаление тегов

Остается удалить теги. Мы создадим функцию для удаления тегов.

Построчное разбиение

removeTag = (i) => {

Я не буду говорить о функции стрелки, потому что мы делали это в прошлый раз. Чтобы указать, какой тег нужно удалить, я буду использовать индекс. Если вы выполните какую-либо сортировку или переупорядочение своих тегов, это не сработает, но для моего примера это будет: P

const newTags = [ ...this.state.tags ];

Мы не хотим напрямую изменять состояние компонента, поэтому мы создаем новый массив, распространяющий текущие теги, чтобы мы могли удалить теги. Примечание: это не то же самое, что настройка const newTags = this.state.tags.

newTags.splice(i, 1);

Теперь удаляем тег из массива.

this.setState({ tags: newTags });

Сохраните новый список тегов обратно в состояние.

Вызов функции удаления

Теперь мы можем использовать эту функцию, добавив onClick к кнопкам удаления.

Добавьте теги, нажмите "Удалить" и убедитесь, что они работают.

Добавление Backspace Remove

Другой метод удаления тегов - это возможность нажать клавишу возврата, когда пользователь сосредоточен на вводе и нет значения для удаления последнего тега. Этого легко добиться, добавив условие else if в inputKeyDown.

Это вызывает this.removeTag, и индекс будет просто последним элементом в массиве. Вот он во всей функции:

Style It Up!

Я не хочу вдаваться в детали стиля, так как каждый может захотеть сделать свой компонент другим, а это не является целью данной статьи. Взгляните на окончательный код для руководства по стилю. Рекомендуется использовать flex для отображения тегов и ввода в строке.

Окончательное решение

Ссылка на окончательное решение: https://codepen.io/jerrylow/pen/mvZZpp