React, Flexbox и предварительная загрузка изображений

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

Что мы будем строить

Что тебе понадобится

  • react, create-react-app
  • react-icons (необязательно - можете использовать другие значки, если хотите)
  • Никаких сторонних библиотек!

Кроме того, я установил JSON API, который возвращает фиктивные данные для этого руководства.

Создание макета

Хорошо, допустим, это данные, с которыми мы собираемся работать.

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

  • компонент фона, отвечающий за переключение цвета границы и фонового изображения
  • Компонент категорий, отвечающий за сообщение другим компонентам, к какой категории мы относимся
  • Компонент items, отвечающий за сообщение другим компонентам, какой элемент мы в данный момент отображаем
  • Родительский компонент, который будет транслировать все эти требования в виде состояний

Думаю, это хорошее начало. Мы определили, что нам нужно, так что давайте закодируем это.

HTML и CSS

Сначала мы напишем «статическую» версию приложения. Мы собираемся расположить их в иерархию.

Для стилизации мы будем использовать Flexbox. Это довольно просто, но для базовой высоты мы добавим height: “-webkit-fill-available”, так что компонент-оболочка заполнит весь экран.

Я рекомендую прочитать Руководство Криса Койера по Flexbox, если вы не знакомы с ним. Для создания веб-приложений Flexbox, вероятно, лучший инструмент, который вы можете использовать.

Построение состояний пользовательского интерфейса

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

  • Предметы
  • категории
  • индекс выбранного в данный момент элемента, чтобы компоненты знали, какие данные и изображение потребуются.
  • ширина текста каждой категории, чтобы мы могли добавить анимацию слайдера, мы, вероятно, сможем использовать categories:["cat1", "cat2", ...]

Так это выглядело бы примерно так

И они живут в родительском компоненте (единственный источник правды!).

Обработка состояний пользовательского интерфейса

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

Для расчета ширины мы можем сделать что-то вроде этого:

Мы просматриваем наши фиктивные данные и получаем ширину элемента, произнося width.push(document.getElementById(“category” + i).offsetWidth). offsetWidth - это веб-API, который возвращает ширину макета элемента.

Эта функция должна вызываться сразу после монтирования DOM, поэтому мы можем вызвать ее в componentDidMount методе жизненного цикла React.

Затем мы написали document.getElementById(“category” + i) выше, но этот элемент еще не существует, так что давайте займемся этим сейчас.

Здесь мы повторяем категории, используя функцию JS map. Это key={i} для алгоритма согласования реакции. Обратите внимание, что не рекомендуется использовать индекс ({i}) в качестве ключевого свойства, поэтому, если вы используете его для производства, вы можете вместо этого передать саму категорию (cat).

Наконец, давайте напишем эту slideLeft(i) функцию.

Здесь мы используем тот массив catWidth, который мы вычислили ранее. На основе переданного номера индекса мы можем перебрать ширину и добавить их с помощью оператора +=. Это + 40 для маржи.

Изменение фона и цвета

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

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

Последний штрих: предварительная загрузка

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

Есть несколько способов облегчить это, но для целей этого руководства я собираюсь использовать функцию JS .onload.
Мы собираемся написать preloadImg() функцию и запустить ее внутри componentWillMount() метода жизненного цикла.

.onload - это обработчик событий, который запускается, когда ресурсы загружены. Нам нужно объявить цель как изображение, поэтому используется new Image(). Мы используем this.setState для трансляции, когда изображения загружаются. И теперь мы можем использовать это состояние loading, чтобы указать, что фон является чем-то другим, когда он выполняется.

Заключение и ресурсы

Вот и все!

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

Ресурсы

Счастливого кодирования и счастливых праздников! 🎅🎅🎅