Часть 2

Привет! Ранее мы узнали как создать базовый Header компонент с помощью Material UI и React для достижения статического результата, показанного ниже:

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

К концу этого урока мы достигнем следующего:

Давайте начнем! К вашему сведению: вы можете получить доступ к исходному коду на GitHub, чтобы следить за ним.

1. Использование хуков useEffect () и useState () для настройки скорости реакции

Добавьте следующий код в компонент Header:

Давайте разберем это:

  • Сначала мы настраиваем функцию setResponsiveNess и вызываем ее внутри useEffect(). Это заботится об установке состояния mobileView на true или false в зависимости от innerWidth окна.
  • Мы возвращаем функцию очистки в нашем обратном вызове useEffect. Эта возвращенная функция будет вызвана для выполнения необходимой очистки. Когда компонент отключается, мы хотим удалить прослушиватель событий изменения размера.
  • Затем мы добавляем прослушиватель событий к объекту окна, который отслеживает, когда пользователь изменяет размер окна, и добавляем функцию обратного вызова, которая вызывает setResponsiveness.
  • Мы устанавливаем состояние mobileView внутри нашего useState() хука и деконструируем mobileView из состояния, чтобы мы могли ссылаться на него позже.
  • Наконец, мы убеждаемся, что импортировали useEffect и useState из React.

Теперь в нашем операторе возврата компонента Header добавьте {mobileView ? displayMobile() : displayDesktop()}, чтобы у нас было:

  • В зависимости от того, установлено ли состояние mobileView в true или false, мы будем вызывать либо displayMobile(), либо displayDesktop(). Ранее мы писали displayDesktop(), который возвращает JSX, необходимый для отображения настольной версии нашего заголовка. А теперь напишем displayMobile()!

2. Добавление функции для отображения мобильной панели инструментов

Во-первых, мы импортируем библиотеку @material-ui/icons, чтобы иметь доступ к значку меню, который мы будем использовать. Запустите npm i @material-ui/icons, затем добавьте import MenuIcon from “@material-ui/icons/Menu”; в наш Header компонент. Импортировать IconButton из @material-ui/core. Затем добавьте следующий код в наш компонент Header:

Давайте переварим:

  • Мы оборачиваем MenuIcon (он же значок ящика), который мы импортировали из библиотеки @material-ui/icons/Menu, в IconButton оболочку.
  • Мы передаем некоторые свойства компоненту IconButton (он деструктурируется с использованием синтаксиса ES6): edge: "start" позволяет расположить кнопку в начале панели инструментов. color: "inherit" позволяет значку унаследовать цвет, указанный в ближайшем компоненте верхнего уровня. “aria-label": “menu" и “aria-haspopup": “true" предназначены для программ чтения с экрана, чтобы уведомлять пользователей с нарушениями зрения о том, что этот элемент является меню и имеет всплывающее окно, соответственно.
  • Затем мы помещаем в наш femmecubatorLogo, который был ранее определен, оборачивая его в div.

Теперь, если мы изменим размер экрана, у нас должно получиться:

Чтобы избавиться от заполнения в мобильном представлении, просто добавьте следующее в наш класс заголовка в ловушке makeStyles():

"@media (max-width: 900px)": {
      paddingLeft: 0,
    },

Таким образом, paddingLeft будет 0, когда экран меньше 900 пикселей. Мы должны иметь:

Исправлено заполнение:

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

3. Добавление логики для обработки щелчка кнопки ящика.

  • Добавьте onClick: handleDrawerOpen в наш список опор в IconButton:
  • Напишите функцию handleDrawerOpen в displayMobile():
const displayMobile = () => {
    const handleDrawerOpen = () =>
    setState((prevState) => ({ ...prevState, drawerOpen: true }));
...
  • Добавьте drawerOpen в наш хук useState(), инициализировав его значением false. Кроме того, деконструируйте drawerOpen из состояния, чтобы мы могли ссылаться на переменную позже.
const [state, setState] = useState({
    mobileView: false,
    drawerOpen: false
  });
const { mobileView, drawerOpen } = state;

Итак, теперь, когда мы нажимаем на кнопку со значком меню, drawerOpen будет установлено в true.

4. Добавление компонента ящика на панель инструментов

Затем мы добавляем компонент Drawer в наш Toolbar. Обязательно импортируйте его из @material-ui/core:

Давайте разберемся, что происходит с Drawer:

  • anchor: “left” закрепляет ящик в левой части экрана.
  • open: drawerOpen: В зависимости от того, является ли наше состояние drawerOpen true или false, наше Drawer будет отображаться или не отображаться.
  • onClose: handleDrawerClose гарантирует, что, когда мы щелкнем что-либо за пределами ящика, будет вызываться handleDrawerClose функция. Это позаботится о том, чтобы для состояния drawerOpen было false, таким образом закрывая ящик.

Затем мы добавили div в ящик, вызвав getDrawerChoices(), который отвечает за отображение пунктов меню, по которым пользователь может щелкнуть. Напишем getDrawerChoice функцию:

Что тут происходит:

  • Мы сопоставляем каждый элемент в коллекции headersData, разбирая ключи label и href каждого элемента.
  • Каждый объект отображается на Link и импортируется из @material-ui/core.
  • Мы указываем, что это компонент RouterLink, который мы ранее импортировали из react-router-dom.
  • to: href позволяет пользователю переходить к href маршруту одним щелчком мыши.
  • Мы убеждаемся, что указаны color и key, и устанавливаем textDecoration на none, чтобы удалить подчеркивание ссылки по умолчанию.
  • Наконец, мы используем MenuItem (импортированный из @material-ui/core) и добавляем в него наш label.

Когда мы сейчас щелкаем по значку меню, мы видим:

И нажатие на каждый из этих пунктов меню приведет нас к соответствующему маршруту.

Последнее, что нужно сделать, это добавить немного отступов в наш ящик.

  • Добавьте класс drawerContainer к нашему div, который содержит варианты выбора ящиков:
<Drawer anchor="left" open={drawerOpen} onClose={handleDrawerClose}>
   <div className={drawerContainer}>{getDrawerChoices()}</div>
</Drawer
  • Затем задайте стиль drawerContainer в makeStyles():
const useStyles = makeStyles(() => ({
...
  drawerContainer: {
    padding: "20px 30px",
  }
}));

И вуаля!

Заключение

Получите доступ к исходному коду на GitHub. Не стесняйтесь настраивать по своему вкусу!

Кроме того, дополнительную информацию можно найти в Документации по пользовательскому интерфейсу материалов.

Спасибо за то, что следили за мной. Надеюсь, вы нашли этот урок полезным!