Построение функциональности поиска и фильтрации в React 🦄

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

Недавно я создал приложение React с нуля в качестве проекта кодирования Bootcamp. Приложение называется Scientific Foodie, это база данных, которая делится научной информацией обо всех различных видах пищи, таких как фрукты, овощи, зерно, тыква и многое другое:

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

В этом приложении мои компоненты Search и Filter работают в тандеме, поэтому ниже я расскажу об этапах создания каждого компонента и о том, как я, и вот подсказка, связал их вместе.

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


Создание компонента фильтра 📌

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

  1. В родительском компоненте создайте состояние, которое будет фиксировать выбранный пользователем фильтр. Мне нравится устанавливать состояние по умолчанию для моего фильтра «Все», которое является первым параметром в компоненте Filter. «Все» обеспечивает отображение всего при загрузке страницы, и во время фильтрации пользователь может вернуться к просмотру всего в любой момент.

  2. Далее мы создадим простую функцию обратного вызова для перехвата значения event.target.value, которое является изменением фильтра, и обновления состояния. Изначально я всегда настраиваю свою вспомогательную функцию на консольный журнал выбора, просто чтобы знать, что мой обратный вызов работает — подробнее об этом чуть позже.

  3. Передайте вспомогательную функцию в качестве реквизита от родительского компонента к дочернему компоненту Filter. Это позволит обратному вызову принадлежать другому компоненту, а не тому, который его вызывает.

  4. Для функциональности фильтра требуется событие onChange. Просто назначьте вспомогательную функцию в качестве реквизита для onChange. Каждый раз, когда выбирается опция фильтра, значение передается через нашу вспомогательную функцию родительскому компоненту.

  5. Попробуйте это, чтобы убедиться, что это работает! Как вы узнаете? Помните, что у нас есть временный консольный журнал в вспомогательной функции в нашем родительском компоненте. В своем приложении выберите опцию фильтра и посмотрите значение, записанное в консоль. Еще раз убедитесь, что значения опций соответствуют вашим данным.

  6. Теперь, когда вы знаете, что обратный вызов работает, удалите консольный журнал и замените его функцией-установщиком вашего состояния. И добавьте еще один временный консольный журнал, чтобы проверить значение переменной state. В своем приложении снова выберите фильтр, и вы увидите, как ваше состояние фиксирует изменение фильтров в консоли! Наконец, удалите консольный журнал.


Создание компонента поиска 🔎

Оставив компонент Filter в стороне, давайте пока создадим наш Search.

  1. Установите состояние в родительском компоненте верхнего уровня, в моем случае FoodContainer. Значением по умолчанию для состояния поиска должна быть пустая строка.

  2. Создайте простую функцию обратного вызова для обработки того, что набирается в строке поиска. Как и в случае с функцией-помощником фильтра, настройте функцию-помощник поиска на консольный лог текста в строке поиска. Мы хотим убедиться, что она работает.

  3. Далее ваш компонент Search должен принять два реквизита: переменную состояния поиска и вспомогательную функцию. Мы передаем состояние как реквизит, потому что создаем управляемый компонент.

  4. В компоненте Search значение должно принимать переменную состояния поиска в качестве реквизита, а функция onChange принимает обратный вызов помощника в качестве реквизита. Ваш помощник перехватывает event.target.value.

  5. Попробуйте это, чтобы убедиться, что все работает! С временным журналом консоли в нашей функции помощника поиска в родительском компоненте введите что-нибудь в строке поиска. В консоли вы увидите, что каждое нажатие клавиши регистрируется как одна буква за раз. Это нормально! Мы пока не обновляем состояние; мы только ведем консольный журнал, чтобы убедиться, что обратный вызов работает правильно.

  6. Затем удалите этот консольный журнал и замените его функцией-установщиком состояния поиска. Затем добавьте еще один временный консольный журнал, чтобы проверить, что состояние обновляется правильно, и снова введите текст в строке поиска. Вы увидите текст в консоли и слово, сформированное в строке поиска. Круто! Поскольку это управляемый компонент с состоянием, назначенным в качестве поискового значения, буквы появляются в строке поиска по мере ввода, т.е. пользователь наблюдает за обновлением состояния в реальном времени.

  7. Наконец, удалите последний консольный журнал.


Объединение фильтра и поиска ⛓

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

Мой родительский компонент FoodContainer управляет отображением продуктов на странице, поэтому именно в него я добавил следующий код:

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

  2. Напишите оператор if. Если выбранный фильтр — «Все», то будут возвращены все элементы массива. Это записывается как return true. В противном случае возвращаются элементы, соответствующие выбранному пользователем фильтру.

Мы могли бы остановиться на этом, но мы хотим, чтобы поиск и фильтр работали вместе, чтобы пользователь мог использовать и то, и другое. Еще пара шагов:

  1. Далее подключим еще один фильтр. Теперь наша переменная, foodsToDisplay, учитывает и фильтр, и код поиска, а не одно или другое. Цепочка методов — это вызов методов один за другим в одном операторе, что позволяет сделать ваш код лаконичным и продолжить логику.

  2. В моем случае я позволяю пользователям искать продукты питания по общему названию. includes добавляется потому, что я хочу возвращать частичные совпадения по мере того, как пользователь набирает текст. Наконец, я преобразовываю общее название и поиск в нижний регистр, чтобы капитализация не мешала.

TLDR 😎 — либо пользователь ищет по всем продуктам, либо ищет по отфильтрованному выбору.

Теперь, наконец, давайте составим карту нового массива! Как только это будет сделано, опробуйте поиск и фильтрацию в своем приложении. Это довольно круто.

Итак, как все прошло у меня? Вот как получился мой React-проект:

Оцените статью
devanswers.ru
Добавить комментарий