Привет хабр!  Недавно на одном из проектов, появилась потребность добавить на страницу фильтры, которые не должны терять данные при перезагрузке страницы и автоматически устанавливать значения при переходе по ссылке. Логичным решением стало использовать параметры url страницы в качестве источника данных. Но если таких страниц на вашем проекте много, а количество фильтров может отличаться, то встает вопрос, можно ли как то сделать универсальную функцию в которой будет инкапсулироваться основные действия, ведь не хочется для каждой страницы заново писать код.  Раз уж так сейчас  стало популярным использовать и писать свои hooks, давайте попробуем написать свой кастомный hook, который будет удовлетворять этим требованиям. Но сначала немного разберемся с понятиями. Параметры в URL — это последовательность символов, расположенных после адреса. Для их отделения от основного URL используется знак вопроса. Каждый параметр представляет собой пару ключ=значение. Для отделения пар друг от друга используется знак «&». Например у нас есть страница со списком сотрудников, в которой есть query параметры. https://example-web-page/employees?name=Bob&surname=Jordan&position=engineer В процессе написания hook будем использовать React, React Router, TypeScript Начнем с простого, опишем наш фильтр. Далее опишем функцию, которая будет из фильтра делать query строку URLSearchParams не поддерживается старыми браузерами и IE. Если требуется поддержка, то используйте методы stringify и parse из query-string, подробнее о нем  можно узнать здесь И наоборот из query строки будем делать фильтр. Далее будем использовать hooks, которые нам предоставляет React Router:  useHistory, useLocation. Подробнее о них можно почитать в документации Начнем собирать наш кастомный hook Итак, при открытии страницы из URL мы будем получать значения фильтров. Теперь нам нужно, чтобы при изменении фильтра у нас менялись значения query параметров. Напишем функцию, которая будет устанавливать новое значение. Использование replace или push  зависит от требований, если вы хотите записывать в историю все изменения фильтра то можно использовать push, в моем случае достаточно записать только последнее. Подробнее о методах можно посмотреть в документации React Router  Теперь напишем функции, которые будем передавать в качестве callback function из нашего кастомного hook. Нам потребуется функция для изменения фильтра  Функция  для удаления значения из фильтра В качестве вспомогательной функции, использовали omit из lodash, которая будет удалять свойство из объекта Cоберём всё это в наш кастомный hook, но перед этим сделаем несколько изменений для того, чтобы он стал универсальным для разных фильтров. Добавим типизацию в нашем кастомный hook для передачи правильных типов в компоненты. Добавим, в качестве необязательных параметров, две  функции для обработки фильтра и query строки для более сложных фильтров Обернем функции в useCallback для мемоизации ссылок и useMemo для мемоизации фильтра После выполнения данных действий, получим описание типов, которые будут передаваться их нашего hook. И сам кастомных hook Функции которые передаются в качестве параметров в useFiltersQuery, можно было не передавать в данном примере, но для более сложных фильтров это потребуется сделать.  Например если нам потребуется сделать из одного query параметра несколько фильтров, или как в примере ниже, получить данные по идентификатору. В  этом  варианте для примера используем методы stringify и parse из query-string для случая когда требуется поддержка старых браузеров. Посмотрим как его можно вызывать из компонента В случае усложнения обработки фильтров нужно будет прокидывать эти функции в useQueryFilters  в качестве параметров.  Пример вызовов функций кастомного hook из самого фильтра, это может быть как dropdown так и input для поиска Это может быть как dropdown так и input для поиска, так и другие варианты Вот и все, мы получили наш hook, который можно использовать для фильтров на разных страницах. В написании hook, нет ничего сложного. Ведь любой hook – это такая же функция, которая требует лишь несколько правил: Начало функции должно начинаться со слова use, это говорит о том, что это hook.  Выполнять hooks следует в самом верху иерархии функционального компонента React (нельзя вызывать hooks в условиях и циклах) Вызывать hooks можно только в React функциях или функциональных компонентах React или вызывать hooks из кастомных hooks (как сделано в нашем примере) Более подробнее о правилах, можно посмотреть в документации React. Надеюсь статья была полезной для вас.   Удачного кодинга, друзья! Всем Пока Frontend Developer