Олег Марков
Обзор популярных библиотек для React
Введение
React стабильно остается одним из самых востребованных инструментов для разработки современных веб-приложений. Простота архитектуры, удобство JSX и богатая поддержка сообщества сделали его отличным выбором для создания масштабируемых интерфейсов. Но при работе над реальным проектом часто встает вопрос: как расширить стандартные возможности React? Здесь на помощь приходят различные сторонние библиотеки.
В мире React существует множество решений для управления состоянием, роутинга, стилизации, UI-компонентов, запросов к API, тестирования и других задач. В каждом таком направлении есть свои лидеры, которые заслуженно считаются "must-have" инструментами. В этом обзоре вы найдете знакомство с основными из них — я расскажу не только о назначении, но и приведу практические примеры, чтобы вы могли легко начать использовать их в своих проектах.
Управление состоянием
Redux
Redux — это один из самых известных инструментов управления состоянием в приложениях на React. Он строится на принципах однонаправленного потока данных и использует простую архитектуру: хранилище, экшены, редьюсеры.
Особенности Redux
- Централизованное хранилище состояния
- Предсказуемость и прозрачность изменений
- Встроенная поддержка инструментов отладки (например, Redux DevTools)
Пример использования Redux
Давайте рассмотрим базовый пример добавления Redux в проект на React:
// Импортируем нужные модули
import { createStore } from 'redux'
import { Provider, useSelector, useDispatch } from 'react-redux'
// Определяем редьюсер
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 }
default:
return state
}
}
// Создаем хранилище
const store = createStore(counterReducer)
// Компонент, использующий Redux
function Counter() {
const count = useSelector((state) => state.count) // Получаем значение из хранилища
const dispatch = useDispatch() // Диспатчим действия
return (
<div>
<span>{count}</span>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
</div>
)
}
// Включаем Redux в корне приложения
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
)
}
Здесь я показываю вам, как устроено базовое подключение Redux: создаете редьюсер, хранилище, компонент получает состояние и диспатчит действия. Для крупных приложений обычно используют middleware, такие как redux-thunk или redux-saga для асинхронных операций.
Экосистема React предлагает множество полезных библиотек, которые упрощают разработку и расширяют функциональность приложений. Знание популярных библиотек позволяет разработчикам быстрее решать задачи и создавать более качественные приложения. Если вы хотите получить обзор популярных библиотек для React и узнать, как их использовать — приходите на наш большой курс Основы React, React Router и Redux Toolkit. На курсе 177 уроков и 17 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Zustand
Zustand — это легкая и простая альтернатива Redux, особенно популярна для небольших и средних приложений. Библиотека использует хуки, не требует провайдеров и отличается минималистичным API.
Основные функции Zustand
- Простая интеграция и очень низкий порог входа
- Иммутабельность состояния без дополнительных библиотек
- Хорошо работает с TypeScript
Пример использования Zustand
Смотрите, я покажу вам, как быстро создать глобальное хранилище состояния с помощью Zustand:
import create from 'zustand'
// Создаем хранилище с хук-сигнатурой
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}))
function Counter() {
const { count, increment } = useStore() // Просто используем хук
return (
<div>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
)
}
В отличие от Redux, здесь вам не нужна отдельная конфигурация провайдеров или редьюсеров — все настраивается максимально просто и понятно.
React Context
React Context не является отдельной библиотекой, это собственная функция React для передачи глобальных данных внутрь дерева компонентов, минуя пропсы. Она отлично подходит для темизации, настройки локализации и передачи простых глобальных настроек.
Применение Context
import React, { createContext, useContext, useState } from 'react'
// Создаем контекст
const ThemeContext = createContext()
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('dark')
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
)
}
function ThemedButton() {
const { theme, setTheme } = useContext(ThemeContext) // Достаем данные из контекста
return (
<button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
Theme: {theme}
</button>
)
}
function App() {
return (
<ThemeProvider>
<ThemedButton />
</ThemeProvider>
)
}
Контекст лучше всего использовать для состояния, которым делятся многие компоненты, и которое редко изменяется.
Роутинг
React Router
React Router — стандарт отрасли для организации маршрутизации и перехода по страницам в приложениях на React. Позволяет создавать одностраничные приложения с удобными адресами и вложенной структурой страниц.
Основные особенности React Router
- Простая организация путей и вложенных маршрутов
- Динамические параметры URL
- Программная навигация и охранники маршрутов
Пример использования React Router
Покажу вам, как устроить базовую навигацию:
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'
function Home() {
return <h2>Главная</h2>
}
function About() {
return <h2>О нас</h2>
}
function App() {
return (
<Router>
<nav>
<Link to="/">Главная</Link>
<Link to="/about">О нас</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Router>
)
}
В этом примере у вас есть две страницы, и переход между ними осуществляется без перезагрузки.
Стилизация
styled-components
styled-components — популярная библиотека для написания CSS прямо в JS через т.н. CSS-in-JS подход. Позволяет создавать компоненты с инкапсулированными стилями и поддерживает theming.
Ключевые возможности styled-components
- Динамические и условные стили
- Автоматическая генерация уникальных имен классов
- Поддержка темизации
Пример использования styled-components
Вот пример, который поможет вам быстрее понять принцип работы:
import styled from 'styled-components'
// Создаем компонент с инкапсулированным стилем
const Button = styled.button`
background: ${(props) => (props.primary ? 'blue' : 'gray')};
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
`
function App() {
return (
<div>
<Button>Обычная кнопка</Button>
<Button primary>Главная кнопка</Button>
</div>
)
}
Как видите, стили полностью изолированы, а пропсы позволяют создавать варианты компонента.
Emotion
Emotion — еще одна библиотека CSS-in-JS с похожим API, часто используемая с TypeScript из-за хорошей типизации. Предлагает как styled-API, так и функцию css для inline-стилей.
Пример использования Emotion
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'
function App() {
return (
<div
css={css`
background: papayawhip;
padding: 20px;
`}
>
Стилизованный блок
</div>
)
}
Emotion хорошо себя показывает в крупных проектах — ее выбирают, если важна скорость сборки и гибкая настройка стилизации.
UI-компоненты
Material-UI (MUI)
MUI предоставляет огромный набор готовых компонентов, оформленных в стиле Material Design. Отличный выбор для быстрой верстки панели управления, внутренних инструментов и сайтов.
Особенности MUI
- Библиотека с гибкой кастомизацией тем
- Предустановленные компоненты — кнопки, таблицы, диалоги, формы и др.
- Легко интегрируется с styled-components и Emotion
Пример использования MUI
Здесь я размещаю пример, чтобы вам было проще понять:
import Button from '@mui/material/Button'
function App() {
return (
<Button variant="contained" color="primary">
Нажми меня
</Button>
)
}
Изменять цвет, размер и другие параметры можно с помощью пропсов или темизации.
Ant Design
Ant Design — еще один мощный фреймворк UI-компонентов, часто применяется для бизнес-приложений благодаря выраженному корпоративному стилю.
Пример использования Ant Design
import { Button } from 'antd'
import 'antd/dist/antd.css'
function App() {
return <Button type="primary">Нажми меня</Button>
}
Библиотека также поддерживает темизацию через переменные стилей.
Запросы данных и управление серверным состоянием
React Query
React Query — инструмент для эффективной работы с асинхронными запросами и кеширования данных. Помогает синхронизировать состояние клиентского приложения с сервером, автоматизирует повторные запросы, обработку ошибок и обновление данных.
Особенности React Query
- Простой API для выполнения запросов, мутаций и обновления кэша
- Фоновое обновление данных (refetch)
- Поддержка пагинации, бесконечной прокрутки и управления ошибками
Пример использования React Query
Показываю вам, как устроить запрос к серверу:
import { useQuery, QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient()
function App() {
return (
<QueryClientProvider client={queryClient}>
<Users />
</QueryClientProvider>
)
}
function Users() {
// useQuery автоматически кэширует и управляет состоянием
const { isLoading, error, data } = useQuery(['users'], () =>
fetch('/api/users').then((res) => res.json())
)
if (isLoading) return <div>Загрузка...</div>
if (error) return <div>Ошибка: {error.message}</div>
return (
<ul>
{data.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
React Query автоматически обновит данные при фокусе, рендере, а также предоставляет удобные хуки для мутаций.
Axios
Axios — библиотека для запросов HTTP, часто используется вместе с React Query или самостоятельно.
import axios from 'axios'
async function getUsers() {
const response = await axios.get('/api/users')
return response.data
}
Axios позволяют удобно обрабатывать запросы, ошибки и поддерживает отмену запросов.
Тестирование
Jest
Jest — стандартная тестовая среда для приложения на React. Она поддерживает снапшот-тестирование, позволяет писать юнит и интеграционные тесты, хорошо интегрируется с другими инструментами.
Пример использования Jest
// Простой пример теста компонента
import { render, screen } from '@testing-library/react'
import App from './App'
test('компонент App содержит кнопку', () => {
render(<App />)
// Проверяем, что кнопка есть
expect(screen.getByText(/Нажми меня/i)).toBeInTheDocument()
})
React Testing Library
React Testing Library ориентируется на поведение пользователя и делает акцент на тестировании реальных сценариев использования, а не структуры компонентов.
Пример использования React Testing Library
import { render, fireEvent } from '@testing-library/react'
import Counter from './Counter'
test('клик по кнопке увеличивает счетчик', () => {
const { getByText } = render(<Counter />)
const button = getByText(/нажми/i)
// Проверяем начальное значение счетчика
expect(getByText(/0/)).toBeInTheDocument()
// Нажимаем на кнопку
fireEvent.click(button)
// Проверяем, что счетчик увеличился
expect(getByText(/1/)).toBeInTheDocument()
})
Эта связка (Jest + React Testing Library) обеспечивает быстрые и удобные тесты компонентов.
Анимация
Framer Motion
Framer Motion — удобная библиотека для добавления анимаций на сайт. Простое, декларативное API позволяет быстро оживить интерфейс и добавить плавные переходы.
Пример анимации с Framer Motion
import { motion } from 'framer-motion'
function App() {
return (
<motion.div
initial={{ opacity: 0 }} // С какой прозрачности начинать
animate={{ opacity: 1 }} // До какой прозрачности анимировать
transition={{ duration: 1 }} // Длительность анимации
>
Плавное появление компонента!
</motion.div>
)
}
Эта библиотека отлично подходит если вам нужны сложные анимации и переходы между страницами.
Формы
React Hook Form
React Hook Form облегчает работу с формами. Она минимизирует количество рендеров, реализует валидацию и позволяет удобно управлять полями.
Пример формы с React Hook Form
import { useForm } from 'react-hook-form'
function MyForm() {
const { register, handleSubmit, formState: { errors } } = useForm()
const onSubmit = data => {
// Отправка данных формы
console.log(data)
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('email', { required: true })} placeholder="Email" />
{errors.email && <span>Обязательное поле</span>}
<button type="submit">Отправить</button>
</form>
)
}
Эта библиотека отлично работает с кастомными и динамическими компонентами форм, помогает держать структуру кода чистой.
Заключение
В мире React большое количество библиотек, каждая из которых закрывает определенную потребность: от управления состоянием и стилизации до роутинга, UI-компонентов и тестирования. Выбор зависит от задач, размера проекта и личных предпочтений команды. Используйте этот обзор для быстрого старта, глубокого сравнения инструментов и построения архитектуры своего приложения.
Знание библиотек расширяет возможности React. Для создания сложных приложений требуется умение управлять состоянием и роутингом. Рассмотрите курс Основы React, React Router и Redux Toolkit для получения необходимых навыков. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в основы React уже сегодня.
Частозадаваемые технические вопросы по теме статьи и ответы на них
Вопрос 1. Как выполнить миграцию с Redux на Zustand или Context, если проект уже большой?
Ответ:
Переходите поэтапно. Начните оборачивать новые или несложные фичи в Zustand/Context, а старый Redux-дев- код оставляйте как есть. Постепенно выносите логику из useSelector/useDispatch в новые хуки состояния, двигаясь с Feature-Scoped подходом. Следите, чтобы не было дублирующих источников истины для одних и тех же данных.
Вопрос 2. Почему React Router ломает обновление страницы (F5, прямой заход по адресу)?
Ответ:
Если сервер не настроен на отдачу index.html для любого пути, напрямую введенный URL или F5 вызовет 404. Настройте web-сервер (например, Nginx или Express), чтобы любые несуществующие пути отдавали index.html. Это нужно для корректной работы client-side роутера.
Вопрос 3. Как типизировать Zustand или Redux store с помощью TypeScript?
Ответ:
Для Redux опишите интерфейсы стейта и экшенов, используйте их типы в редьюсерах и хранилище. Для Zustand можно предоставить дженерики в create, добавить типизацию для функций и возвращаемых значений, чтобы получить автокомплит и проверки типов на каждом этапе работы.
Вопрос 4. Как сделать асинхронный запрос с помощью React Context?
Ответ:
Вынесите запросы в useEffect в провайдере Context, храните результат в useState, обновляйте value провайдера после завершения запроса. Контролируйте состояние загрузки и ошибок — предоставьте их вместе с данными через value контекста.
Вопрос 5. Как подключить Ant Design с модульными стилями или styled-components?
Ответ:
В AntD традиционно используется Less, но чтобы интегрировать с CSS modules или styled-components, оберните компоненты AntD в стилизованные оболочки, стилизуйте className/Style пропы или используйте override темизации через переменные Less (configureWebpack — less-loader).
Постройте личный план изучения React до уровня Middle — бесплатно!
React — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по React
Лучшие курсы по теме

React и Redux Toolkit
Антон Ларичев
TypeScript с нуля
Антон Ларичев