Redux - это библиотека для управления состоянием приложения. Она основана на трех принципах:
Единственный источник правды: все состояние приложения хранится в одном объекте.
Состояние только для чтения: единственный способ изменить состояние - отправить действие.
Изменения делаются с помощью чистых функций: редюсеры - это чистые функции, которые принимают предыдущее состояние и действие, и возвращают новое состояние.
Redux Thunk: Redux Thunk - это middleware для Redux, который позволяет работать с асинхронной логикой. С его помощью вы можете:
Отправлять функции вместо простых объектов действий.
Откладывать отправку действий.
Отправлять действия, если выполняются определенные условия.
Ключевая терминология:
Store: объект, который хранит состояние приложения.
Action: простой объект, описывающий, что произошло в приложении.
Reducer: чистая функция, которая принимает текущее состояние и действие, и возвращает новое состояние.
Dispatch: метод store, который используется для отправки действий.
Middleware: функции, которые обрабатывают действия до того, как они достигнут редюсера.
Thunk: функция, которая может быть отправлена как действие с помощью Redux Thunk.
Selector: функция, которая извлекает определенные данные из состояния.
Файл slice (срез) - это концепция, введенная в Redux Toolkit для упрощения работы с Redux. Slice объединяет логику редюсеров и действий в одном месте.
Redux Thunk:
Простота: Легко изучить и использовать.
Функции: Позволяет отправлять функции вместо простых объектов действий.
Асинхронность: Хорошо подходит для простых асинхронных операций.
Контроль потока: Ограниченные возможности для сложного контроля потока выполнения.
Тестирование: Относительно просто тестировать.
React Saga:
Сложность: Имеет более крутую кривую обучения.
Генераторы: Использует генераторы JavaScript для управления потоком выполнения.
Эффекты: Предоставляет набор эффектов для сложных асинхронных операций.
Контроль потока: Мощные возможности для управления сложными потоками асинхронных операций.
Тестирование: Легко тестировать благодаря предсказуемости генераторов.
Отмена операций: Встроенная поддержка отмены длительных операций.
Параллелизм: Удобные инструменты для работы с параллельными задачами.
Основные отличия:
Парадигма: Thunk использует функции, Saga использует генераторы.
Сложность: Saga более мощная, но и более сложная в освоении.
Масштабируемость: Saga лучше подходит для крупных приложений со сложной логикой.
Тестируемость: Saga обычно легче тестировать из-за своей декларативной природы.
Функциональность: Saga предоставляет больше встроенных инструментов для сложных сценариев.
// Redux thunk
export const fetchUser = (userId) => async (dispatch) => {
dispatch({ type: 'FETCH_USER_START' });
try {
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();
dispatch({ type: 'FETCH_USER_SUCCESS', payload: userData });
} catch (error) {
dispatch({ type: 'FETCH_USER_ERROR', payload: error.message });
}
};
// Redux saga
export const fetchUser = (userId) => async (dispatch) => {
dispatch({ type: 'FETCH_USER_START' });
try {
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();
dispatch({ type: 'FETCH_USER_SUCCESS', payload: userData });
} catch (error) {
dispatch({ type: 'FETCH_USER_ERROR', payload: error.message });
}
};
Vite - это современный инструмент сборки, разработанный Evan You (создателем Vue.js). Он предназначен для быстрой разработки и сборки современных веб-приложений.
Основные особенности Vite:
Быстрый старт: Использует нативные ES-модули браузера для мгновенного запуска сервера разработки.
Быстрая сборка: Использует Rollup для оптимизированной сборки продакшн-версии.
Поддержка TypeScript из коробки.
Встроенная поддержка CSS, JSON, и статических ресурсов.
Оптимизация для production: Автоматическая предварительная сборка зависимостей.
Базовый конфиг Vite (vite.config.js):
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: {
port: 3000
},
build: {
outDir: 'build'
}
})
Отличия от Webpack:
Скорость: Vite значительно быстрее в режиме разработки, так как не требует полной сборки для старта.
Конфигурация: Vite требует меньше конфигурации и проще в настройке.
Модули: Vite использует нативные ES-модули в разработке, Webpack использует свою систему модулей.
Экосистема: Webpack имеет более обширную экосистему плагинов и лоадеров.
Сравнение скорости:
Запуск сервера разработки: Vite обычно запускается за секунды, в то время как Webpack может занимать десятки секунд.
Обновление при изменениях: Vite обновляет только измененные модули, что делает Hot Module Replacement (HMR) очень быстрым.
Сборка для продакшн: Vite и Webpack показывают сопоставимую производительность.
CRACO с Webpack: CRACO (Create React App Configuration Override) - это инструмент для настройки Create React App без необходимости его "извлечения" (eject).
Отличия CRACO от Vite:
Базовая технология: CRACO работает поверх Webpack, в то время как Vite использует свой подход.
Экосистема: CRACO позволяет использовать всю экосистему Webpack без извлечения CRA.
Конфигурация: CRACO требует дополнительного конфигурационного файла (craco.config.js) для настройки.
Скорость разработки: Vite обычно быстрее в режиме разработки.
Пример конфигурации CRACO (craco.config.js):
module.exports = {
webpack: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
plugins: [
// дополнительные плагины Webpack
],
},
jest: {
configure: {
// настройки Jest
},
},
};
Выбор между Vite, Webpack и CRACO зависит от ваших конкретных потребностей:
Vite отлично подходит для новых проектов, особенно если важна скорость разработки.
Webpack (с или без CRACO) может быть лучшим выбором для существующих проектов или когда требуется специфическая конфигурация и широкая экосистема плагинов.
CRACO полезен, когда вы хотите настроить проект Create React App без извлечения конфигурации.
yarn add -D vite-plugin-svgr
// vite-env.d.ts
/// <reference types="vite/client" />
declare module '*.svg?react' {
import React from 'react';
const SVGComponent: React.FC<React.SVGProps<SVGSVGElement>>;
export default SVGComponent;
}
// vite config
import svgr from 'vite-plugin-svgr';
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path';
import envCompatible from 'vite-plugin-env-compatible';
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill';
export default defineConfig({
plugins: [
react(),
svgr({
svgrOptions: {
icon: true,
}
}),
envCompatible()
],
server: {
port: 3000
},
// root: 'public',
build: {
outDir: 'build',
},
define: {
global: {},
process: {}
},
resolve: {
alias: {
app: '/src/app',
entities: '/src/entities',
features: '/src/features',
pages: '/src/pages',
shared: '/src/shared',
widgets: '/src/widgets',
process: 'process/browser'
},
},
optimizeDeps: {
esbuildOptions: {
// Node.js global to browser global polyfills
define: {
global: 'globalThis'
},
plugins: [
NodeGlobalsPolyfillPlugin({
buffer: true
}),
NodeModulesPolyfillPlugin()
]
}
}
})

