Как сделать чтобы скролл был внизу react

Обновлено: 08.07.2024

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

React-scrollbars-custom

К достоинствам данной библиотеки можно отнести собственное поведение прокрутки браузера – оно не имитирует прокрутку, показывает только настраиваемые полосы прокрутки, сама прокрутка все еще родная.

Библиотека поддерживает кроссбраузерность и кроссплатформенность – неважно, где и как будет открыта страница, полосы прокрутки везде будут выглядеть одинаково. Также для её работы никаких дополнительных таблиц стилей не требуется.

Gemini-scrollbar

gemini-scrollbar – добавляет пользовательские оверлейные полосы прокрутки с собственным механизмом прокрутки. Это еще одна библиотека, которая при небольшом размере и легкости настройки, поможет вам создавать кастомные полосы прокрутки и подгонять их под дизайн ваших страниц.


Smooth-scrollbar

smooth-scrollbar – это библиотека на JavaScript, используемая для создания настраиваемой, производительной полосы прокрутки с эффектами плавной прокрутки для перемещения содержимого страницы.


Vuescroll

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


SimpleBar

SimpleBar – это простая автономная библиотека JavaScript, которая добавляет настраиваемую полосу прокрутки к любому прокручиваемому контейнеру с содержимым. Работает со свойством CSS overflow: auto и сохраняет собственное поведение прокрутки.


Malihu

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


OverlayScrollbars

OverlayScrollbars – это библиотека JavaScript, используемая для создания элегантных, настраиваемых и тематических полосок прокрутки на любых прокручиваемых элементах.


Slim-scroll

Slim-scroll – это плагин на чистом JavaScript, который заменяет встроенную полосу прокрутки браузера на полосу, которую можно легко настроить с помощью CSS.


SimpleScrollbar

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


Perfect-scrollbar

perfect-scrollbar – это небольшая библиотека, написанная полностью на JavaScript. С её помощью вы сможете делать стильные полоски прокрутки, видоизменяя их по своему желанию. Для изменения полосок вы можете использовать как уже готовые варианты CSS, так и создать свои.


Baron

Baron – небольшая, быстрая и кроссбраузерная настраиваемая полоса прокрутки с собственной механикой прокрутки системы. Если вам нужно быстрое и легкое решение – то эта библиотека для вас.

NanoScroller.js

nanoScroller.js – это плагин jQuery, который предлагает простой способ реализации полос прокрутки. Он копирует стиль Mac OS X Lion и приносит его на ваши страницы. Он использует минимальную разметку HTML .nano > .nano-content. Другие элементы div полосы прокрутки .pane > .nano-slider реализуются при загрузке страницы, что позволяет упорядочить содержимое шаблона. В последней версии была реализована встроенная прокрутка и совместимость с iPad, iPhone и некоторыми планшетами на Android.


FakeScroll

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

Плагин рейтинга создан автором этого блога. Буду очень признателен, если вы сможете его поддержать (ссылка)

Как стилизовать или убрать полосу прокрутки — CSS скроллбар

Стилизованные полосы прокрутки становятся популярными, думаю, вы уже сталкивались с такими сайтами, которые имеют уникальный скроллбар (к примеру, наш сайт). Есть два способа реализации этой задачи: с помощью CSS3 или используя jQuery плагин. Мы будем использовать наиболее простой — напишем CSS стили.

полоса прокрутки css

Примечание: стилизовать полосу прокрутки через -webkit префикс возможно только в браузерах, использующих механизм рендеринга Webkit (и Blink). То есть в Firefox и IE этот способ не сработает.

Часто бывает необходимо убрать или скрыть скроллбар css совсем. Для начала, давайте рассмотрим как это сделать.

1 Как убрать полосу прокрутки CSS

Скрыть полосу прокрутки можно как у отдельного элемента на странице, так и у всей страницы целиком. Сделать это не сложно, достаточно написать следующее свойство:

2 Как изменить скроллбар CSS

Теперь давайте рассмотрим базовую структуру полосы прокрутки:

стилизация полосы прокрутки

-webkit-scrollbar состоит различных псевдо-элементов.

  1. ::-webkit-scrollbar — это фон самого скроллбара.
  2. ::-webkit-scrollbar-button — кнопки направления на полосе прокрутки.
  3. ::-webkit-scrollbar-track — пустое пространство под индикатором прокрутки.
  4. ::-webkit-scrollbar-thumb — индикатор прокрутки, перетаскиваемый элемент.

Проверим как все это работает. Чтобы попробовать изменить скроллбар css, создадим пустой HTML документ. Вам необходимо добавить style.css ваш HTML файл. В разметку добавим div с id element, имеющий полосу прокрутки, чтобы применить на него наши стили.

3 CSS стили

Для того, чтобы у элемента div появилась полоса прокрутки, добавим следующие свойства.

Если вы хотите изменить ширину скролла всей страницы, а не отдельного элемента, то используйте ::-webkit-scrollbar без дополнительных селекторов.

Мы уже знаем, что скроллбар состоит из полосы, кнопки и индикатора прокрутки. Используем псевдо элемент ::-webkit-scrollbar-thumb , для того чтобы стилизовать индикатор.

Добавим свойство box-shadow полосе, чтобы добавить скроллбару контрастность. Подобрать подходящую тень можно в нашем box-shadow генераторе.

В заключении: вот еще несколько вариантов, которые вы можете использовать на своем сайте.

ancient_scroll_1600_clr

Скролл-эффекты – это тренд, возникший в веб-дизайне несколько лет назад и все еще набирающий обороты. В этой статье я попытаюсь рассказать о популярных разновидностях таких эффектов, привести несколько примеров реального использования и поделиться шикарным инструментом для комфортной работы с ними.

Мы будем называть scroll-эффектами любые сценарии и приемы, реализуемые на веб-странице, так или иначе связанные с направлением и/или позицией прокрутки этой страницы относительно окна браузера.

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

1. Parallax (Параллакс).

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

Например, в этом демо надпись Parallax – ScRolling in the Deep движется медленнеe скролла вниз и плавно исчезает, при этом задний фон верхней части страницы движется вверх немного быстрее скролла.

2. Back to top (Вернуться вверх).

Приятная и полезная кнопка “Back to top” изначально скрыта, появляется только тогда, когда страница немного проскроллена вниз. Вот демо.

3. Sticky (Прилипание)

Суть техники заключается в том, что элемент при скролле ведет себя как position: relative относительно своего родителя, пока его верхняя граница не достигнет верхнего края окна (viewport-a). При дальнейшем скролле вниз элемент ведет себя как position: static , будто отвязывается от родителя и “прилипает” к границе окна. Вот, к примеру, демо, в котором верхняя панель навигации реализована c эффектом “sticky”.

Этой техникой также можно пользоваться для “прилепливания” элементов к нижней, левой или правой границе экрана, в зависимости от позиции и направления скролла.

Надо сказать, что СSS свойство position: sticky (позволяет с легкостью реализовывать подобные эффекты без применения javascript) описано в черновике спецификации CSS Positioned Layout Module Level. Но вот с поддержкой браузерами пока совсем туго.

4. Reversed sticky (Реверсное прилипание).

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

5. Progress bar (Индикатор прокрутки).

Разновидности сценариев для визуализации текушего положения пользователя на странице при скролле. Например, в этом демо есть веселый индикатор прокрутки внизу страницы.

6. Accordion (Аккордеон).

Этот сценарий подразумевает последовательное применение stcicky-эффекта к заголовкам разделов страницы при скролле. А вот и демо

7. Menu Spy (Сопровождающее меню).

Этот сценарий хорошо известен под именем scroll spy в twitter bootstrap. Он подразумевает подсветку пунктов меню навигации, в зависимости от положения скролла, например, как в этом демо.

8. Staging (Сцена).

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

Общие проблемы при реализации любых сценариев со скролл-эффектами.

Во-первых, при написании скролл-эффектов нужно учитывать большое количество факторов и величин:

  • Размер всего документа.
  • Размеры и позиции элементов, участвующих в сценарии, а также в некоторых случаях и их контейнеров.
  • Размер и текущее положение видимой части документа (viewport) при скролле.
  • Направление скролла.
  • Адаптация при изменении размеров окна с отзывчивым (responsive) дизайном

Во-вторых, математические вычисления для описания сценариев получаются довольно массивными, а их сложность возрастает с ростом количества эффектов.

В-третьих, на мобильных девайсах все работает плохо и с тормозами. Javascript изначально работает медленнее. В добавок к этому, мобильные браузеры блокируют выполнение javascript во время скролла.

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

Что такое Scroolly?

Scroolly – это jquery-плагин, который предоставляет Вам простой синтаксис для создания и конфигурирования скролл-эффектов. Он прост в освоении, довольно легковесный и позволяет создавать сколь угодно сложные сценарии. Нужно сказать, что все демо, которые были приведены выше, реализованы с помощью Scroolly!

Правила, их границы и области действия.

Итак, в процессе скролла, в зависимости от положения прокрутки сраницы, нам нужно применять к элементам некоторые правила. Для этого необходимо определить границы действия этих правил.

Чтобы было проще понять о чем идет речь, приведу абстрактный пример:

  1. Нужно плавно показать и плавно скрыть некоторый элемент, когда при скролле он будет входить в область видимости и выходить из нее. Элемент должен начать появляться после того, как его верхняя кромка будет на 100px выше нижней границы видимой области окна и полностью появится, когда его нижняя кромка будет на 100px выше нижней границы видимой области окна. Та же логика с исчезновением, только в симметрично обратном порядке.
  2. Элемент нужно повернуть на 180° во время скролла, пока он будет находится в зоне ±30% от центра видимой зоны.

Чертовски сложно воспринимается на слух, не правда ли? Лучше посмотрим на демо.

Давайте договоримся, что мы будем называть видимую область документа словом “viewport”. К сожалению, я не могу найти короткий русский аналог этого слова :)

В итоге, здесь мы можем выделить 3 области действия правил c 6-ю границами. Давайте опишем их:

  1. Точка, находящаяся на 100px ниже верхней границы элемента, совпадает с нижней границей viewport (элемент начинает появляться)
  2. Точка, находящаяся на 100px выше верхней границы элемента, совпадает с нижней границей viewport (элемент заканчивает появляться)
  3. Точка, находящаяся на 30% ниже центра viewport, совпадает с центром элемента (элемент начинает поворот)
  4. Точка, находящаяся на 30% выше центра viewport, совпадает с центром элемента (элемент заканчивает поворот)
  5. Точка, находящаяся на 100px ниже верхней границы элемента, совпадает с верхней границей viewport (элемент начинает исчезать)
  6. Точка, находящаяся на 100px выше верхней границы элемента, совпадает с верхней границей viewport (элемент заканчивает исчезать)

А теперь подумайте, с чего Вы начали бы описывать всю эту логику? Даже в таком простом сценарии с одним элементом в вычислениях участвуют размер документа, размер viewport, положение viewport, размер элемента, положение элемента, положение скролла… черт возьми, как же не запутаться?

Scroolly спешит на помощь.

Вся прелесть scroolly заключается в том, что каждая из этих границ областей действия правил задается с помощью вот такого наглядного синтаксиса:

  1. el-top = vp-bottom - 100px (элемент начинает появляться)
  2. el-bottom = vp-bottom - 100px (элемент заканчивает появляться)
  3. el-center = vp-center + 30vp (элемент начинает поворот)
  4. el-center = vp-center - 30vp (элемент заканчивает поворот)
  5. el-top = vp-top + 100px (элемент начинает исчезать)
  6. el-bottom = vp-top + 100px (элемент заканчивает исчезать)

А весь сценарий описывается так:

Где vp – viewport, а el – элемент. Также можно пользоваться абстракциями doc для документа и con для контейнера элемента. А теперь об этом подробнее и с картинками…

leading-actors (2)

У каждого из них есть опорные точки, которые можно использовать в синтаксисе scroolly:

viewport: vp-top , vp-center , vp-bottom
элемент: el-top , el-center , el-bottom
контейнер: con-top , con-center , con-bottom
документ: doc-top , doc-center , doc-bottom

anchors (2)

Вот несколько примеров описания областей действия правил c помощью синтаксиса scrolly:

viewport-document

viewport-element (5)

Документация

Если Вас заитересовал плагин scroolly обязательно посмотрите официальную документацию. А она существует, и даже представлена в 2-х вариантах:

Ну и самое главное: обязательно посмотрите видео с нашей конференции 4front, на котором Борис сам захватывающе рассказал про скролл-эффекты в целом и scroolly в частности.

В заключение


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

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

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

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

Хотите узнать, как создавать собственные хуки React при создании крутых реальных приложений? Переходите по ссылке React Bootcamp .

1. Хук useCopyToClipboard

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

Однако вместо того, чтобы использовать стороннюю библиотеку, я захотел воссоздать эту функциональность с помощью моего собственного хука React. Как и в случае с любым создаваемым хуком, я помещаю файл с его кодом в специальную папку, обычно называемую utils или lib . Далее она используется для хранения файлов с разработанными мною функциями, которые я повторно использую в своем проекте.

Код с новым хуком будет находится в файле useCopyToClipboard.js, в который я также помещу функцию с тем же именем.

Существует несколько различных способов реализовать копирование текста в буфер обмена пользователя. И ранее для этого, я обычно предпочитал использовать проверенную библиотеку из пакета copy-to-clipboard , что делает процесс разработки более быстрым и надежным.

В следующем примере кода мы экспортируем из пакета функцию copy , которую далее при необходимости будем вызывать в своем коде.

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

Разрабатываем функцию handleCopy

После проверки типа, полученное содержимое и преобразуем в строку, которую передаем в импортируемую функцию copy . Затем мы возвращаем функцию handleCopy из хука в любое место нашего приложения.

Функция handleCopy будет связана с обработчиком onClick для соответствующих кнопок.

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

Начальное значение переменной isCopied будет задано логическим значением false . Если текст был успешно скопирован, то после вызова функции copy установим значение isCopied равным true . В противном случае – false .

И наконец, мы будем возвращать из функции хука массив, содержащий переменную состояния isCopied вместе с функцией handleCopy .

Отлично, теперь мы можем использовать хук useCopyToClipboard в любом компоненте, где нам это необходимо.

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

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

Добавляем интервал сброса состояния кнопки копирования

Как мы уже говорили, после успешного копирования текста с помощью нашего хука значение переменной isCopied становится истинным (и таким впоследствии остается). Это означает, что мы и далее будем постоянно видеть значок успешного копирования.

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

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

Добавим стандартный хук useEffect , в который передадим значение интервала сброса состояния resetInterval и переменную isCopied . После успешного копирования и передачи соответствующего значения переменной isCopied , мы запускаем функцию-таймер setTimeout с временем срабатывания равным интервалу сброса, после чего возвращаем переменной isCopied значение false .

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

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

2. Хук usePageBottom

В приложениях React в некоторых случаях важно знать, когда пользователь прокрутил страницу до конца.

Как и ранее, начнем с создания в нашей папке utils отдельного файла usePageBottom.js в который добавим функцию (хук) с тем же именем:

И так, нам необходимо определить момент, когда пользователь попадет в нижнюю часть страницы. Мы можем определить его произведя несложные расчеты, используя информацию, полученную из свойств глобального объекта window . Отметим, что перед тем как обращаться к нему, нам нужно убедиться, что компонент, в котором вызывается хук, смонтирован. Для этого мы будем использовать хук useEffect , в который передадим пустой массив зависимостей.

Пользователь будет прокручивать страницу до конца, то есть до тех пор пока значение свойства window.innerHeight плюс значение свойства document.scrollTop не станет равным document.offsetHeight . Таким образом, если результат проверки этого условия будет истинным, то будем считать пользователь прокрутил страницу до конца:

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

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

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

Разрешить эту проблему можно возвращая из хука useEffect функцию, в которую обернем метод window.removeEventListener и передадим ему ссылку на функцию handleScroll .

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

3. Хук useWindowSize

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

Для этого мы могли бы в файле с разметкой JSX использовать медиа-запрос CSS или пользовательский хук React, предоставляемый сторонней библиотекой, чтобы в зависимости от текущего размера страницы скрывать или показывать ее элементы.

Раньше я использовал хук, импортируемый из библиотеки react-use , но вместо того, чтобы каждый раз подключать целую библиотеку, я решил создать свой собственный. Этот хук, который я назвал useWindowSize , при необходимости вычислял бы размеры окна, то есть его ширину и высоту и возвращал эти значения в нужном месте кода.

Разработка хука

Для начала в нашей папке utils создадим новый js файл с тем же именем, что и название хука useWindowSize . Затем я импортирую React, для того чтобы использовать стандартные хуки в коде нашего хука и его корректного экспорта.

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

То есть для корректной работы хука нам необходимо предусмотреть тот факт, что наш код может работает как в браузере, так и на сервере. Для его определения мы можем проверить соответствие результата выполнения выражения typeof window и строки undefined .

В случае для браузера по умолчанию, мы можем возвращать из функции хука объект, содержащий свойства с фиксированными значениями ширины и высоты, допустим, 1200 и 800 пикселей:

Как получить ширину и высоту окна

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

При изменении размера окна будет вызвана функция обратного вызова, и состояние компонента, а точнее значение переменной windowSize будет обновлено с учетом текущих размеров окна браузера. Для этого используются значения ширины и высоты из объекта window.innerWidth и window.innerHeight .

Как добавить поддержку SSR (серверного рендеринга)

Тем не менее с использованием технологии SSR, код в том виде работать не будет. Это связано с тем, что ключевое правило хуков состоит в том, что их нельзя вызывать при необходимости в зависимости от выполнения каких-либо условий. Как результат этого ограничения, мы не можем для их проверки использовать условные операторы до вызова хуков useState , либо useEffect .

Далее мы будем использовать тернарный оператор для установки значений ширины и высоты, предварительно проверив, находимся ли мы на сервере. Если это так, мы будем использовать значение по умолчанию, а если нет, мы будем использовать значения из объекта window.innerWidth и window.innerHeight .

И наконец, в конце кода хука вернем значение переменной состояния windowSize .

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

Этот хук будет также корректно работать с любым серверным приложением React, таким как Gatsby и Next.js.

4. Хук useDeviceDetect

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

Я отследил причину проблемы до одной сторонней библиотеки под названием response-device-detect , которую я использовал, чтобы определять, использует ли пользователь для просмотра сайта мобильное устройство или нет. И если это так, я бы убирал слишком большой заголовок из-за которого ломалась страница.

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

Работа над кодом хука

Как и ранее я создал в моей папке utils отдельный файл с тем же именем, useDeviceDetect.js. И поскольку хуки – это просто функции JavaScript для общего назначения, которые используются механизмом хуков в React, я создаю функцию с тем же именем useDeviceDetect и импортирую React.

Как получить информацию о пользовательском агенте user agent

Способ, которым мы воспользуемся, чтобы определить тип устройства, которое использует пользователь – это получить и проанализировать значение свойства userAgent , которое в свою очередь содержится в свойстве navigator глобального объекта окна window .

А поскольку взаимодействие с интерфейсом окна браузера window API, как и с API внешнего ресурса можно в общем случае рассматривать как побочный эффект, то мы можем получить доступ к информации о пользовательском агенте внутри кода хука useEffect .

После монтирования компонента используем инструкцию кода typeof navigator , чтобы определить, выполняется код в браузере или же на сервере. Если мы находимся на сервере, то у нас соответственно не будет доступа к объекту window . Поэтому результат выполнения выражения typeof navigator будет эквивалентен строке undefined , поскольку этого свойства не существует. В противном случае (код выполняется в браузере) мы можем получить значение свойства, содержащего информацию о пользовательском агенте, способом описанном выше.

Используем тернарный оператор для получения данных userAgent следующим образом:

Как определить, соответствует ли значение userAgent мобильному устройству

Значение свойства userAgent представляет собой строку, которая содержит следующие имена устройств, соответствующие мобильным устройствам: Android, BlackBerry, iPhone, iPad, iPod, Opera Mini, IEMobile или WPDesktop.

И всё, что нам нужно сделать это, используя полученную строку и метод match() с соответствующим регулярным выражением, проверить содержит ли она одну из перечисленных строк. Логическое значение, полученное в результате выполнения проверки сохраним в локальной переменной с именем mobile .

Далее сохраним полученный результат в состоянии компонента, используя хук useState , которому при вызове присвоим начальное значение false . Для этого создадим переменную состояния isMobile , и соответствующую ей функцию-сеттер setMobile .

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

В возвращаемый объект добавим значение isMobile :

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

Заключение

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

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

Читайте также: