Отзывчивое приложение на React менее чем за 30 минут
В сегодняшней статье мы шаг за шагом создадим небольшое, но многофункциональное адаптивное приложение React с нуля быстрым и удобным для разработчиков способом, используя Material UI.
MUI предоставляет простую, настраиваемую и доступную библиотеку компонентов React.
В нашем приложении будут следующие функции:
- Сворачиваемый контент (Home)
- Сортируемая таблица данных с разбивкой по страницам (About Us)
- Форма с разными категориями входных данных (Contact Us)
- Адаптивная галерея изображений. (Shop)
Требования:
- Базовые знания React, некоторое представление о хуках
- Минимальный опыт работы с пользовательским интерфейсом Material UI
Material UI терминология:
- App Bar — встроенный компонент, который является базовой навигацией по веб-сайту
- Toolbar — структура элементов навигационной панели, т.е. строка / столбец
- Material Icons — включает более 2100 официальных значков шрифтов Google Material, преобразованных в компоненты SvgIcon.
- Typography — используется для оформления текстового контента на веб-сайте
- Tabs — они помогают организовать и разрешить навигацию между группами контента, которые связаны и находятся на одном уровне иерархии, например: ссылки на меню
- Drawer — он обеспечивает доступ к местам назначения в вашем приложении.
- useMediaQuery — это CSS-хук медиа-запроса для React. Он прослушивает совпадения с медиа-запросом CSS. Это позволяет отображать компоненты в зависимости от того, соответствует запрос или нет.
- useTheme — настройте MUI в соответствии с вашей темой. Вы можете изменить цвета, типографику и многое другое.
@react_tg – React в телеграме.
Шаги создания
Чтобы создать новое приложение React, выполните приведённую ниже команду в вашем терминале:
$ npx create-react-app my-responsive-app
Перейдите в папку “my-responsive-app” и выполните приведённую ниже команду, чтобы запустить приложение:
$ npm start
Приложение будет отображаться в браузере по URL, http://localhost:3000 .
Далее установите зависимости пользовательского интерфейса материала. Запустите 1 из приведённой ниже команды в зависимости от того, что вы используете (NPM / YARN):
$ npm install @mui/material @emotion/react @emotion/styled
#ИЛИ
$ yarn add @mui/material @emotion/react @emotion/styled
Далее мы установим несколько значков пользовательского интерфейса Material UI:
$ npm install @mui/icons-material
#ИЛИ
$ yarn add @mui/icons-material
Давайте испачкаем наши руки… 🤓
Рекомендую, установить расширение React Snippets, чтобы быстрее писать код на React. Расширение предоставляет вам фрагменты React / Redux для VS code.
Оно поддерживает:
JavaScript (.js) / JavaScript React (.jsx)
TypeScript (.ts) / TypeScript React (.tsx)
Выполнив описанные выше действия по установке, вы можете перейти в свой редактор кода, удалить весь код по умолчанию из src/App.js
файла и обновить его, как показано ниже:
function App() {
return (
<div>
</div>
);
}
export default App;
Создайте новый заголовок компонента в папке src и импортируйте его внутри компонента приложения. Компонент заголовка будет иметь Appbar по умолчанию, предоставляемый Material UI, мы также добавляем Toolbar для выравнивания элементов панели приложений в строке.
import React from 'react'
import AppBar from '@mui/material/AppBar';
import { Toolbar, Typography } from '@mui/material';
//Header Component with responsive menu
function Header() {
return (
<React.Fragment>
<AppBar>
<Toolbar>
<Typography>
Sample Text
</Typography>
</Toolbar>
</AppBar>
</React.Fragment>
)
}
export default Header
Добавьте образец значка логотипа из библиотеки пользовательского интерфейса Material UI.
import AbcIcon from '@mui/icons-material/Abc';
<AbcIcon fontSize="large"></AbcIcon>
Настройте стиль компонента AppBar в соответствии с вашими потребностями:
<AppBar sx={{background: '#063970'}}>
Теперь мы создадим меню в базовом стиле с кучей ссылок, используя компонент Tabs в Material UI, как показано ниже:
//Create a state hook, to store value of selected menu item
const [selectedMenuVal, setSelectedMenuVal] = useState(0)
<Tabs sx={{ fontWeight: "500"}} value={selectedMenuVal} onChange={(e, value)=>{ setSelectedMenuVal(value)}} textColor="inherit" indicatorColor='primary'>
<Tab label="Home" />
<Tab label="About Us" />
<Tab label="Contact Us" />
<Tab label="Shop" />
</Tabs>
Мы добавляем ‘indicatorColor’ в компонент Tabs для отображения текущей нажатой или активной ссылки с подчёркиванием, которое будет отличать её по внешнему виду от других ссылок меню. Активной ссылке по умолчанию присвоено значение “home”
Затем мы используем хук ‘useState’ для сохранения значения текущего выбранного пункта меню в переменной состояния ‘selectedMenu’. Поскольку это входная переменная, мы используем событие ‘onChange’ для отслеживания значения последней нажатой ссылки.
Давайте теперь добавим компонент панели “search“, используя стилизованный ввод и значок поиска, и импортируем его в App.js:
function SearchInput() {
return (
<Search>
<SearchIconWrapper>
<SearchIcon />
</SearchIconWrapper>
<StyledInputBase
placeholder="Search…"
inputProps={{ 'aria-label': 'search' }}
/>
</Search>
)
}
export default SearchInput
После добавления логотипа, меню и панели поиска мы добавим кнопку “login” в наше приложение.
{/* Create a wrapper grid aligned to right */ }
<Grid container justifyContent="flex-end">
{/* Search */}
<SearchInput />
{/* Login Button */}
<Button variant='contained' sx={{marginLeft: "1.5ch"}}>Login</Button>
</Grid>
К концу вышеуказанных шагов ваше приложение будет выглядеть так, как показано на рисунке ниже:
На данный момент, если изменить размер вашего окна, то вкладки и кнопки начнут перекрываться и полностью разорвут страницу, потому что мы еще не сделали её адаптивной 😂
Теперь мы “оживим” наше приложение! 🤩
Адаптивный веб-дизайн (RWD) – это подход к веб-разработке, который создаёт динамические изменения внешнего вида веб-сайта в зависимости от размера экрана и ориентации устройства, используемого для его просмотра.
Более подробную информацию об адаптивном веб-дизайне можно найти здесь.
Давайте теперь сделаем наше приложение отзывчивым.
Мы создадим пользовательский компонент DrawerComp, используя функцию ‘drawer’ из Material UI.
function DrawerComp() {
// Create an openDrawer state variable and set it to false by default
const [openDrawer, setOpenDrawer] = useState(false)
return (
<React.Fragment>
<Drawer open={openDrawer} onClose={() => {setOpenDrawer(false)}}>
<List>
<ListItemButton>
<ListItemIcon>
<ListItemText>Login</ListItemText>
</ListItemIcon>
</ListItemButton>
</List>
</Drawer>
<IconButton onClick={() => setOpenDrawer(!openDrawer) }>
<MenuIcon></MenuIcon>
</IconButton>
</React.Fragment>
)
}
Как мы можем видеть в приведённом выше фрагменте кода, внутри компонента DrawerComp мы храним значения открытия и закрытия drawer в переменной состояния и переключаем значение на true / false с помощью функции onClick, установленной на кнопке MenuIcon. Drawer содержит список ссылок, например, для входа в систему (login).
Теперь мы добавим useMediaQuery & useTheme hooks из Material UI, чтобы выборочно отображать содержимое страницы в соответствии с текущим размером экрана.
useTheme hook предоставляет нам объект ‘theme’, как показано на рисунке ниже. У него есть свойство с именем ‘breakpoint’, которое содержит массив ‘keys’ со всеми размерами экрана, такими как (x-small, small, medium, large, x-large).
//Boolean variable checks if screen size is smaller than medium
const theme = useTheme();
const isMatch = useMediaQuery(theme.breakpoints.down('md'))
//We create a turnary statement, which renders drawer component when screen size is < medium
isMatch ? `hamburger menu` : `normal menu with Tabs structure`
Здесь мы создаём 2 константы массива со всеми ссылками на пункты меню и перебираем их, чтобы создать меню вкладок и компонент меню внутри ящика.
export const mainMenu = ["Home", "About Us", "Contact Us", "Shop"]
export const hamburgerMenu = [...mainMenu, "Login"]
Теперь ваше приложение будет выглядеть так, как показано ниже, на экранах меньшего размера:
Соберите содержимое “Tab”
Home — Теперь мы добавим компонент Card, который содержит следующие подкомпоненты:
- CardHeader — текстовый заголовок и подзаголовок
- CardMedia — Изображения или видео (медиа), которые будут связаны с содержимым карты
- CardContent — Текстовое описание
- CardActions — Пользователь может выполнять такие действия, как добавление в избранное / поделиться в социальных сетях
- Expandmore — Пользовательский компонент, который в основном представляет собой ссылку “узнать больше”.
- Collapse — компонент пользовательского интерфейса материала для отображения/скрытия дополнительного описания
About Us — На этой вкладке мы будем создавать компонент Data-grid. Мы будем отображать данные в табличной форме,
Вам нужно будет выполнить приведенную ниже команду в терминале:
npm install @mui/x-data-grid
function AboutUs() {
return (
<div style={{ height: 400, width: '80%', margin: "0 auto" }}>
<DataGrid
rows={rows}
columns={columns}
pageSize={5}
rowsPerPageOptions={[5]}
checkboxSelection
/>
</div>
)
}
Таблицы данных отображают информацию в сетчатом формате строк и столбцов. Они организуют информацию таким образом, чтобы её было легко сканировать, чтобы пользователи могли искать закономерности и идеи.
Contact Us — На этой вкладке мы создаём форму с различными категориями полей ввода, такими как текст, номер, поле выбора, ввод и только для чтения.
Shop — на этой вкладке отображается галерея “image”, структура и изображения которой являются адаптивными и автоматически настраиваются в соответствии с размером экрана. Для создания этой галереи мы будем использовать “woven” вариант макета из библиотеки MUI.
<>
<Typography sx={{fontSize: "1.5rem", fontWeight: "bold", margin: "20px auto", textAlign: "center"}}>
Game Of Thrones Characters Image Gallery
</Typography>
<ImageList sx={{ width: "70%", height: 750, border: "1px solid #ddd", borderRadius: "5px", padding:"10px", margin: "10px auto", boxShadow: "0 0 10px #eee" }} cols={3} variant="woven" rowHeight={164}>
{gotCharacters.map((char) => (
<ImageListItem key={char.img}>
<img
src={`${char.img}?w=200&h=200&fit=crop&auto=format`}
srcSet={`${char.img}?w=200&h=200&fit=crop&auto=format&dpr=2 2x`}
alt={char.title}
loading="lazy"
/>
<ImageListItemBar position="below" title={char.title} sx={{ fontFamily: "Times New Roman", fontStyle: "italic", fontWeight: "bold" }} />
</ImageListItem>
))}
</ImageList>
</>
Полный код
Полный исходный код этого приложения можно найти в этом репозитории.
Пожалуйста, обратите внимание, что это бета-версия, дальнейшие улучшения и исправления ошибок будут добавлены в следующих статьях очень скоро. Не стесняйтесь делиться, создавать, тестировать, открывать этот проект.
Заключение
По мере того, как React продолжает развиваться и раздвигать границы возможностей фронтенд-разработчиков, нам также необходимо переосмыслить способы создания наших приложений. Мы должны сделать их надёжными, масштабируемыми, простыми в модификации, слабо связанными и более быстрыми в сборке.
Библиотеки, подобные MUI, помогают нам достичь скорости без ущерба для качества и доступности.
Имейте в виду, что это не единственный подход к ускорению создания приложений React, но это действительно оптимальное решение, простое, которое вы можете сделать сами, даже если у вас есть только базовые знания в области веб-разработки.