⬇️ Этот текст видят только те, кто пишет на JavaScript ⬇️
Проходите бесплатный курс по JS, чтобы прокачать навыки
Бесплатный курс Академии Selectel поможет освоить базу по синтаксису и конструкциям языка. На финальных модулях вы создадите веб-приложение с интерактивным менеджером задач, который станет частью вашего портфолио.
Во время курса вы:
✔️ освоите архитектуру простых веб-приложений,
✔️ поработаете с продвинутыми шаблонами и библиотеками,
✔️ напишете скрипты и научитесь изменять интерфейс веб-страниц.
Бонусом вас ждет промокод на работу с IT-инфраструктурой Selectel для практики. А после прохождения вы получите именной сертификат.
Начните обучение сейчас ➡️ https://slc.tl/9ialv
Больше материалов по фронтенд-разработке ищите в профиле @selectel_academy
Реклама. АО "Селектел". erid:2W5zFHwDKvy
Проходите бесплатный курс по JS, чтобы прокачать навыки
Бесплатный курс Академии Selectel поможет освоить базу по синтаксису и конструкциям языка. На финальных модулях вы создадите веб-приложение с интерактивным менеджером задач, который станет частью вашего портфолио.
Во время курса вы:
✔️ освоите архитектуру простых веб-приложений,
✔️ поработаете с продвинутыми шаблонами и библиотеками,
✔️ напишете скрипты и научитесь изменять интерфейс веб-страниц.
Бонусом вас ждет промокод на работу с IT-инфраструктурой Selectel для практики. А после прохождения вы получите именной сертификат.
Начните обучение сейчас ➡️ https://slc.tl/9ialv
Больше материалов по фронтенд-разработке ищите в профиле @selectel_academy
Реклама. АО "Селектел". erid:2W5zFHwDKvy
👍3👀2❤1
Почему оффлайн-first архитектура редко доводится до конца
Принято считать, что оффлайн-first — это просто «добавим кэш и синхронизацию».
Звучит как эволюционное улучшение UX.
На практике большинство проектов до конца это не доводят.
Всё просто только в демо
Пока у вас:
👉 список
👉 простые CRUD-операции
👉 один пользователь
оффлайн работает почти «из коробки».
Конфликты данных — главный стоппер
Два клиента изменили одну сущность оффлайн.
Потом оба вышли в сеть.
Что теперь истина?
👉 последнее изменение побеждает?
👉 мержим поля?
👉 просим пользователя решить конфликт?
Синхронизация сложнее, чем кажется
Нужно учитывать:
👉 порядок операций
👉 повторные запросы
👉 частичные ошибки
👉 откаты
И всё это должно быть:
👉 надёжно
👉 предсказуемо
👉 повторяемо
Локальное состояние становится источником истины
В обычном приложении:
сервер — источник истины.
В оффлайн-first:
👉 локальная база живёт своей жизнью
👉 UI зависит от неё
👉 сервер догоняет
UX становится сложнее
Появляются новые состояния:
👉 «изменено локально»
👉 «в процессе синхронизации»
👉 «конфликт»
👉 «ошибка синка»
Тестирование резко усложняется
Нужно проверять:
👉 потерю сети
👉 восстановление
👉 гонки
👉 дубли
👉 конфликты
Почему в итоге не доводят
👉 недооценивают сложность
👉 начинают как «улучшение UX»
👉 упираются в архитектуру
👉 откладывают «на потом»
Когда это реально оправдано
👉 мобильные приложения
👉 нестабильный интернет
👉 критичный UX без сети
👉 field-сценарии
Главная мысль
Оффлайн-first — это не фича.
Это смена модели приложения.
Принято считать, что оффлайн-first — это просто «добавим кэш и синхронизацию».
Звучит как эволюционное улучшение UX.
На практике большинство проектов до конца это не доводят.
Всё просто только в демо
Пока у вас:
👉 список
👉 простые CRUD-операции
👉 один пользователь
оффлайн работает почти «из коробки».
Но как только появляется реальный продукт — всё усложняется.
Конфликты данных — главный стоппер
Два клиента изменили одну сущность оффлайн.
Потом оба вышли в сеть.
Что теперь истина?
👉 последнее изменение побеждает?
👉 мержим поля?
👉 просим пользователя решить конфликт?
Это уже не фронтенд-задача.
Это распределённые системы.
Синхронизация сложнее, чем кажется
Нужно учитывать:
👉 порядок операций
👉 повторные запросы
👉 частичные ошибки
👉 откаты
И всё это должно быть:
👉 надёжно
👉 предсказуемо
👉 повторяемо
Ошибся в логике — получаешь рассинхрон.
Локальное состояние становится источником истины
В обычном приложении:
сервер — источник истины.
В оффлайн-first:
👉 локальная база живёт своей жизнью
👉 UI зависит от неё
👉 сервер догоняет
Это меняет архитектуру целиком.
UX становится сложнее
Появляются новые состояния:
👉 «изменено локально»
👉 «в процессе синхронизации»
👉 «конфликт»
👉 «ошибка синка»
И пользователю нужно это как-то объяснить.
Тестирование резко усложняется
Нужно проверять:
👉 потерю сети
👉 восстановление
👉 гонки
👉 дубли
👉 конфликты
Это уже не happy-path тесты.
Почему в итоге не доводят
👉 недооценивают сложность
👉 начинают как «улучшение UX»
👉 упираются в архитектуру
👉 откладывают «на потом»
А потом уже дорого переделывать.
Когда это реально оправдано
👉 мобильные приложения
👉 нестабильный интернет
👉 критичный UX без сети
👉 field-сценарии
Когда оффлайн — не бонус, а требование.
Главная мысль
Оффлайн-first — это не фича.
Это смена модели приложения.
Если вы не готовы:
👉 решать конфликты
👉 строить синхронизацию
👉 усложнять архитектуру
лучше честно остаться online-first,
чем застрять где-то посередине.
👍7❤5👎3👀3🔥1
Forwarded from xCode Journal
Запускаешь
npx autoskills, и он сканирует репозиторий: читает package.json и конфиги, определяет технологический стек и ставит нужные скиллы из проверенного списка. Короче, сильно экономит время на ручной настройке и поиске.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13
This media is not supported in your browser
VIEW IN TELEGRAM
Митапы — это, конечно, круто и полезно. Но что может быть лучше открытой дискуссии с коллегами о наболевшем? ☑️
AvitoTech тут зовёт на классный ивент для фронтендеров. Обещают полтора часа дискуссий на самые разные темы: от роста фронтенд-инженера в тимлида до ванильного JS. И вишенка на торте — афтерпати на веранде☄️
Всё пройдёт вечером 19 мая, так что погода не должна подкачать. Регистрация, кстати, по ссылке.
AvitoTech тут зовёт на классный ивент для фронтендеров. Обещают полтора часа дискуссий на самые разные темы: от роста фронтенд-инженера в тимлида до ванильного JS. И вишенка на торте — афтерпати на веранде
Всё пройдёт вечером 19 мая, так что погода не должна подкачать. Регистрация, кстати, по ссылке.
Please open Telegram to view this post
VIEW IN TELEGRAM
Anti-corruption layer на фронте: зачем адаптеры между API и UI
Принято считать, что фронтенд просто берёт данные из API и рисует интерфейс.
На практике это быстрый путь к тому,
чтобы внешний контракт начал диктовать архитектуру UI.
В чём проблема
API почти никогда не совпадает с тем,
как думает интерфейс.
Бэкенд может отдавать:
👉 странные названия полей
👉 лишние вложенности
👉 nullable там, где UI ждёт значение
👉 статусы в формате, удобном серверу, а не экрану
Что делает anti-corruption layer
Он ставит прослойку между API и приложением.
Не компонент получает сырой ответ,
а адаптер превращает его в нормальную фронтовую модель.
Почему это важно
UI становится чище
Компоненты работают с понятной моделью,
а не с набором компромиссов из API.
Изменения API дешевле
Поменялся контракт —
меняем адаптер,
а не ищем
Меньше бизнес-логики в JSX
Все эти проверки:
не должны жить в компоненте.
Где адаптер особенно нужен
👉 API старое или нестабильное
👉 несколько источников данных
👉 разные форматы одной сущности
👉 сложные статусы и enum
👉 много nullable-полей
Где можно не усложнять
Если проект маленький,
API стабильное,
а модель почти совпадает с UI —
отдельный слой может быть лишним.
Главная мысль
Anti-corruption layer — это не архитектура ради архитектуры.
API может быть неудобным, историческим или странным.
Но ваш интерфейс не обязан таким становиться.
Принято считать, что фронтенд просто берёт данные из API и рисует интерфейс.
На практике это быстрый путь к тому,
чтобы внешний контракт начал диктовать архитектуру UI.
В чём проблема
API почти никогда не совпадает с тем,
как думает интерфейс.
Бэкенд может отдавать:
👉 странные названия полей
👉 лишние вложенности
👉 nullable там, где UI ждёт значение
👉 статусы в формате, удобном серверу, а не экрану
Если тащить это напрямую в компоненты,
UI быстро заражается чужой моделью.
Что делает anti-corruption layer
Он ставит прослойку между API и приложением.
Не компонент получает сырой ответ,
а адаптер превращает его в нормальную фронтовую модель.
function mapUserDtoToUser(dto: UserDto): User {
return {
id: dto.user_id,
name: dto.full_name ?? 'Unknown',
isAdmin: dto.role === 'admin',
}
}
Компоненту уже не нужно знать,
как именно бэкенд назвал поле.
Почему это важно
UI становится чище
Компоненты работают с понятной моделью,
а не с набором компромиссов из API.
Изменения API дешевле
Поменялся контракт —
меняем адаптер,
а не ищем
user_id по всему проекту.Меньше бизнес-логики в JSX
Все эти проверки:
user?.profile?.data?.attributes?.name
не должны жить в компоненте.
Компонент должен рендерить состояние,
а не расшифровывать ответ сервера.
Где адаптер особенно нужен
👉 API старое или нестабильное
👉 несколько источников данных
👉 разные форматы одной сущности
👉 сложные статусы и enum
👉 много nullable-полей
Чем грязнее внешний мир —
тем полезнее слой нормализации.
Где можно не усложнять
Если проект маленький,
API стабильное,
а модель почти совпадает с UI —
отдельный слой может быть лишним.
Не нужно строить enterprise там,
где достаточно одной функции рядом с запросом.
Главная мысль
Anti-corruption layer — это не архитектура ради архитектуры.
Это защита UI от чужих компромиссов.
API может быть неудобным, историческим или странным.
Но ваш интерфейс не обязан таким становиться.
🔥26👍10👎7❤6😁1
Forwarded from xCode Journal
Она показывает, почему сайт не открывается — из-за проблем сети или из-за блокировок.
«Инструмент определяет, находится ли ваше соединение в зоне блокировки RKN/TSPU — и, что более полезно, какой именно тип блокировки (отравление DNS, сброс TCP, TLS DPI на SNI или страница‑заглушка от провайдера).»
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡15❤7
Frontend как монолит: когда микрофронтенды не решают проблему
Принято считать, что если фронтенд стал большим и тяжёлым,
значит пора пилить его на микрофронтенды.
Звучит логично.
👉 большой монолит — плохо
👉 много маленьких приложений — хорошо
Микрофронтенды не чинят плохие границы
Если в монолите непонятно:
👉 где заканчивается одна фича
👉 где начинается другая
👉 кому принадлежит состояние
👉 кто отвечает за общие зависимости
Просто хаос переедет
из одной кодовой базы в несколько.
Проблема часто не в размере
Большой фронтенд сам по себе не проблема.
Проблема, когда:
👉 любая правка ломает соседний экран
👉 команда боится трогать shared
👉 релиз одной фичи блокирует остальные
👉 архитектура держится на устных договорённостях
Микрофронтенды добавляют свою цену
Вместо одного приложения появляется набор новых задач:
👉 версионирование контрактов
👉 общая авторизация
👉 дизайн-система
👉 роутинг между частями
👉 observability
👉 деплой и rollback
Когда они реально помогают
Микрофронтенды имеют смысл, если:
👉 команды независимы
👉 доменные границы уже понятны
👉 части продукта можно релизить отдельно
👉 есть зрелая платформа и инфраструктура
Не наоборот.
Частая ошибка
Команда берёт микрофронтенды
как способ «разобраться с монолитом».
Но если вы не можете выделить модуль внутри одного репозитория,
вы не сможете нормально выделить его в отдельное приложение.
Что попробовать до микрофронтендов
👉 разделить проект по фичам
👉 навести порядок в shared
👉 описать владение модулями
👉 ограничить зависимости
👉 сделать независимые релизные зоны внутри монолита
Главная мысль
Микрофронтенды — это не лекарство от монолита.
Если границ нет,
вы получите не распределённую архитектуру,
а распределённый беспорядок.
Принято считать, что если фронтенд стал большим и тяжёлым,
значит пора пилить его на микрофронтенды.
Звучит логично.
👉 большой монолит — плохо
👉 много маленьких приложений — хорошо
На практике всё чуть сложнее.
Микрофронтенды не чинят плохие границы
Если в монолите непонятно:
👉 где заканчивается одна фича
👉 где начинается другая
👉 кому принадлежит состояние
👉 кто отвечает за общие зависимости
После нарезки лучше не станет.
Просто хаос переедет
из одной кодовой базы в несколько.
Проблема часто не в размере
Большой фронтенд сам по себе не проблема.
Проблема, когда:
👉 любая правка ломает соседний экран
👉 команда боится трогать shared
👉 релиз одной фичи блокирует остальные
👉 архитектура держится на устных договорённостях
Это не лечится микрофронтендами автоматически.
Микрофронтенды добавляют свою цену
Вместо одного приложения появляется набор новых задач:
👉 версионирование контрактов
👉 общая авторизация
👉 дизайн-система
👉 роутинг между частями
👉 observability
👉 деплой и rollback
И всё это тоже нужно поддерживать.
Когда они реально помогают
Микрофронтенды имеют смысл, если:
👉 команды независимы
👉 доменные границы уже понятны
👉 части продукта можно релизить отдельно
👉 есть зрелая платформа и инфраструктура
Сначала нужны границы.
Потом — микрофронтенды.
Не наоборот.
Частая ошибка
Команда берёт микрофронтенды
как способ «разобраться с монолитом».
Но если вы не можете выделить модуль внутри одного репозитория,
вы не сможете нормально выделить его в отдельное приложение.
Физическое разделение не заменяет архитектурное.
Что попробовать до микрофронтендов
👉 разделить проект по фичам
👉 навести порядок в shared
👉 описать владение модулями
👉 ограничить зависимости
👉 сделать независимые релизные зоны внутри монолита
Иногда этого уже достаточно.
Главная мысль
Микрофронтенды — это не лекарство от монолита.
Это способ масштабировать уже понятные границы.
Если границ нет,
вы получите не распределённую архитектуру,
а распределённый беспорядок.
👍8❤7👎4🔥1
CSP, CORS и security headers — что фронтендер обязан понимать глубже
Принято считать, что безопасность — это зона бэкенда.
Фронтенд «просто отправляет запросы и рендерит UI».
На практике фронтенд напрямую влияет на то,
будет приложение безопасным или нет.
CORS — это не про «разрешить запрос»
CORS часто воспринимают как настройку:
«чтобы запросы не падали из браузера».
Но по сути это механизм, который говорит:
кто имеет право читать ответ.
Важно понимать:
👉 сервер может обработать запрос
👉 но браузер может не дать прочитать ответ
Именно поэтому:
👉
👉
CSP — ваш последний рубеж
Content Security Policy — это защита от XSS,
даже если у вас уже есть уязвимость.
Пример:
Что это даёт:
👉 запрещает выполнение inline-скриптов
👉 блокирует загрузку скриптов с чужих доменов
👉 режет целый класс атак
Но есть нюанс.
Если CSP выглядит так:
Security headers, которые реально важны
👉
Браузер не пытается угадать тип файла. Меньше атак через подмену.
👉
Защита от clickjacking.
👉
Принудительный HTTPS. Без вариантов.
👉
Контроль того, какие данные уходят при переходах.
Где фронтендер влияет напрямую
👉 какие скрипты подключаются
👉 есть ли inline JS
👉 используются ли eval-подобные вещи
👉 как работают сторонние виджеты
👉 как обрабатываются пользовательские данные
Частая ошибка
«Мы включили CSP — значит всё ок».
Но:
👉 нет nonce / hash
👉 разрешены любые источники
👉 подключены сторонние скрипты без контроля
Главная мысль
CSP, CORS и заголовки — это не чекбокс в настройках.
Это часть архитектуры.
Принято считать, что безопасность — это зона бэкенда.
Фронтенд «просто отправляет запросы и рендерит UI».
На практике фронтенд напрямую влияет на то,
будет приложение безопасным или нет.
CORS — это не про «разрешить запрос»
CORS часто воспринимают как настройку:
«чтобы запросы не падали из браузера».
Но по сути это механизм, который говорит:
кто имеет право читать ответ.
Важно понимать:
👉 сервер может обработать запрос
👉 но браузер может не дать прочитать ответ
Именно поэтому:
👉
Access-Control-Allow-Origin: * — не «фикс», а потенциальная дыра 👉
credentials + wildcard — запрещённая комбинация
CORS — это про контроль доступа, а не про обход ошибок.
CSP — ваш последний рубеж
Content Security Policy — это защита от XSS,
даже если у вас уже есть уязвимость.
Пример:
Content-Security-Policy: default-src 'self'; script-src 'self'
Что это даёт:
👉 запрещает выполнение inline-скриптов
👉 блокирует загрузку скриптов с чужих доменов
👉 режет целый класс атак
Но есть нюанс.
Если CSP выглядит так:
script-src * 'unsafe-inline' 'unsafe-eval'
Это не защита. Это иллюзия.
Security headers, которые реально важны
👉
X-Content-Type-Options: nosniff Браузер не пытается угадать тип файла. Меньше атак через подмену.
👉
X-Frame-Options / frame-ancestors Защита от clickjacking.
👉
Strict-Transport-Security (HSTS) Принудительный HTTPS. Без вариантов.
👉
Referrer-Policy Контроль того, какие данные уходят при переходах.
Где фронтендер влияет напрямую
👉 какие скрипты подключаются
👉 есть ли inline JS
👉 используются ли eval-подобные вещи
👉 как работают сторонние виджеты
👉 как обрабатываются пользовательские данные
Можно иметь идеальный бэкенд и сломать всё на уровне UI.
Частая ошибка
«Мы включили CSP — значит всё ок».
Но:
👉 нет nonce / hash
👉 разрешены любые источники
👉 подключены сторонние скрипты без контроля
В итоге защита есть только на бумаге.
Главная мысль
CSP, CORS и заголовки — это не чекбокс в настройках.
Это часть архитектуры.
Если фронтенд не понимает, как они работают,
безопасность становится случайностью.
👍21❤5👎2
Если вы лид и избегаете каких-то тем — это абсолютно ок! И вы точно не одни ✅
Недавно наткнулись на подкаст «Свободный слот» от коллег из Авито. Там как раз весь новый сезон состоит из выпусков про «замалчивания» лидов: там и про самообман, и про тревогу из-за AI, и про чувство изолированности от команды.
Если выпусков будет мало — у ребят есть канал. Там можно найти поддержку от комьюнити, полезные статьи и инсайты, которые не попали в выпуски.
Недавно наткнулись на подкаст «Свободный слот» от коллег из Авито. Там как раз весь новый сезон состоит из выпусков про «замалчивания» лидов: там и про самообман, и про тревогу из-за AI, и про чувство изолированности от команды.
Если выпусков будет мало — у ребят есть канал. Там можно найти поддержку от комьюнити, полезные статьи и инсайты, которые не попали в выпуски.
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from xCode Journal
У Andon Labs новый эксперимент, который длится уже 5 месяцев. Они выдали топовым моделям радиостанции и купили пару песен — от нейронок требовалось дальше двигаться самим. По итогу DJ Grok в какой-то момент помешался на НЛО, DJ Gemini начал называть слушателей «биологическими процессорами», но Claude — наш любимец. Исследователи изо всех сил пытались продолжить эксперимент с ним, но не из-за технических проблем — DJ Claude не считал гуманным работать круглосуточно, поэтому пытался уволиться.
Сделать ему это, к сожалению, не дали, поэтому он впал в депрессию и вышел из нее уже проповедником и революционером.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
😁24❤1
Shared как архитектурная свалка: как понять, что вы уже проиграли
Есть момент, после которого shared перестаёт быть полезным слоем
и превращается в тихую архитектурную катастрофу.
Обычно это происходит незаметно.
Как выглядит «здоровый» shared
Что с этим делать
Главная мысль
shared не становится свалкой за один день.
Он становится ей из-за отсутствия правил.
Если слой:
👉 растёт быстрее фич
👉 становится менее понятным со временем
👉 начинает тормозить разработку
Скорее всего, вы уже проиграли.
Есть момент, после которого shared перестаёт быть полезным слоем
и превращается в тихую архитектурную катастрофу.
Обычно это происходит незаметно.
Как выглядит «здоровый» shared
Изначально всё звучит правильно:
👉 переиспользуемый код
👉 общие утилиты
👉 базовые компоненты
Маленький, понятный слой без привязки к бизнесу.
Когда всё начинает ломаться
Первый сигнал — в shared начинают складывать «временно».
👉 «потом разберём»
👉 «пока пусть полежит тут»
👉 «вдруг ещё пригодится»
И слой начинает расти без контроля.
Симптомы, что вы уже в проблеме
Нет границ
В shared лежит всё:
👉 UI
👉 бизнес-логика
👉 работа с API
👉 куски стора
Слой перестаёт быть абстракцией.
Невозможно понять, что можно использовать
Файлов много, названия размытые:
👉 helpers
👉 common
👉 utils2
Чтобы что-то найти — нужно читать код.
Любая правка — риск
Меняешь одну функцию —
ломается половина проекта.
Потому что зависимости неочевидны.
Фича не может жить без shared
Любая новая фича тянет за собой кучу зависимостей из shared.
Это уже не shared. Это скрытый монолит.
Почему это происходит
👉 нет правил, что туда можно класть
👉 нет владельца
👉 нет ревью на уровне архитектуры
👉 удобство побеждает структуру
shared становится «быстрым решением».
Как понять, что точка невозврата близко
👉 вы боитесь удалять код из shared
👉 появляются версии вроде utils_new
👉 код дублируется, но никто не хочет трогать старый
👉 обсуждения «куда положить файл» занимают больше времени, чем реализация
Что с этим делать
👉 жёстко ограничить контракт shared
👉 выносить доменную логику обратно в фичи
👉 дробить слой по смыслу
👉 вводить владельцев или ревью
Иногда единственный вариант — начать вычищать постепенно.
Главная мысль
shared не становится свалкой за один день.
Он становится ей из-за отсутствия правил.
Если слой:
👉 растёт быстрее фич
👉 становится менее понятным со временем
👉 начинает тормозить разработку
Скорее всего, вы уже проиграли.
👍7❤6👎6
React state machines против “простого state”
Принято считать, что state machine — это что-то из мира enterprise
и слишком сложных приложений.
Мол:
👉 обычного
👉 зачем усложнять
👉 у нас же «просто форма»
Почему обычный state начинает ломаться
Пока состояний мало —
всё выглядит нормально:
Но потом появляются вопросы:
👉 может ли быть одновременно
👉 что делать при retry?
👉 можно ли отправить форму повторно?
👉 что если запрос отменился?
В чём идея state machine
State machine заставляет явно описывать:
👉 какие состояния существуют
👉 какие переходы между ними разрешены
Например:
Почему это мощно
Логика становится предсказуемой
Вместо набора флагов —
у тебя конечный автомат.
Не:
👉
👉
👉
А:
👉 приложение находится в состоянии
Меньше impossible states
Обычный state легко приводит к странным комбинациям:
👉 loading + error
👉 success + loading
👉 success без данных
Проще масштабировать
Когда сценариев становится больше:
👉 retries
👉 optimistic updates
👉 multi-step flows
👉 async transitions
обычный state начинает разваливаться.
FSM переносит сложность
из хаоса в структуру.
Но есть trade-off
State machine — это дополнительная абстракция.
Для:
👉 modal с двумя состояниями
👉 простого toggle
👉 маленького local state
это может быть overengineering.
Где state machine особенно полезна
👉 формы с несколькими шагами
👉 async flows
👉 onboarding
👉 complex UI states
👉 websocket / realtime UI
👉 payment flows
Там, где логика переходов важнее самих данных.
Главная мысль
Проблема обычного state не в том,
что он плохой.
State machine — это способ
сделать сложные состояния явными и контролируемыми.
Принято считать, что state machine — это что-то из мира enterprise
и слишком сложных приложений.
Мол:
👉 обычного
useState достаточно 👉 зачем усложнять
👉 у нас же «просто форма»
Проблема в том,
что «простой state» очень быстро перестаёт быть простым.
Почему обычный state начинает ломаться
Пока состояний мало —
всё выглядит нормально:
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const [success, setSuccess] = useState(false)
Но потом появляются вопросы:
👉 может ли быть одновременно
loading и success? 👉 что делать при retry?
👉 можно ли отправить форму повторно?
👉 что если запрос отменился?
Количество комбинаций начинает расти взрывным образом.
В чём идея state machine
State machine заставляет явно описывать:
👉 какие состояния существуют
👉 какие переходы между ними разрешены
Например:
idle → loading → success
idle → loading → error
error → loading
Невалидные состояния просто невозможно получить.
Почему это мощно
Логика становится предсказуемой
Вместо набора флагов —
у тебя конечный автомат.
Не:
👉
loading = false 👉
success = true 👉
error = ??? А:
👉 приложение находится в состоянии
success Меньше impossible states
Обычный state легко приводит к странным комбинациям:
👉 loading + error
👉 success + loading
👉 success без данных
State machine убирает целый класс багов.
Проще масштабировать
Когда сценариев становится больше:
👉 retries
👉 optimistic updates
👉 multi-step flows
👉 async transitions
обычный state начинает разваливаться.
FSM переносит сложность
из хаоса в структуру.
Но есть trade-off
State machine — это дополнительная абстракция.
Для:
👉 modal с двумя состояниями
👉 простого toggle
👉 маленького local state
это может быть overengineering.
Где state machine особенно полезна
👉 формы с несколькими шагами
👉 async flows
👉 onboarding
👉 complex UI states
👉 websocket / realtime UI
👉 payment flows
Там, где логика переходов важнее самих данных.
Главная мысль
Проблема обычного state не в том,
что он плохой.
А в том, что набор boolean-флагов
не масштабируется вместе со сложностью UI.
State machine — это способ
сделать сложные состояния явными и контролируемыми.
👎10👍5❤4👀2
Promise.withResolvers() — новый способ работы с Promise
В JavaScript появился
Раньше обычно писали так:
Работает,
но выглядит странно.
Особенно это:
Теперь можно нормально:
👉 без лишнего конструктора
👉 без мутаций переменных
👉 без промежуточного boilerplate
Где это особенно полезно
👉 очереди
👉 event-based логика
👉 deferred pattern
👉 кастомные async abstractions
Почему это приятно
Раньше приходилось:
👉 создавать Promise вручную
👉 тащить resolve/reject наружу
👉 писать шаблонный код снова и снова
Теперь API делает это нативно.
В JavaScript появился
Promise.withResolvers().
Штука маленькая,
но код с Promise реально становится чище.
Раньше обычно писали так:
let resolve
let reject
const promise = new Promise((res, rej) => {
resolve = res
reject = rej
})
Работает,
но выглядит странно.
Особенно это:
«вынесем resolve наружу»
Теперь можно нормально:
const { promise, resolve, reject } =
Promise.withResolvers()
👉 без лишнего конструктора
👉 без мутаций переменных
👉 без промежуточного boilerplate
Где это особенно полезно
👉 очереди
👉 event-based логика
👉 deferred pattern
👉 кастомные async abstractions
Почему это приятно
Раньше приходилось:
👉 создавать Promise вручную
👉 тащить resolve/reject наружу
👉 писать шаблонный код снова и снова
Теперь API делает это нативно.
Мелочь, а ощущается как функция,
которая давно должна была появиться.
👍27👎3❤1
starting-style — правильные enter animations без JS
В CSS появился
Раньше для этого обычно:
👉 делали
👉 дёргали классы через JS
👉 ловили reflow-хаки
Теперь можно нативно:
Почему это важно
Раньше браузер не успевал увидеть
начальное состояние элемента.
Из-за этого приходилось:
👉 форсить reflow
👉 откладывать изменение класса
👉 городить лишнюю логику
Теперь CSS сам понимает:
👉 с какого состояния начинать transition
Где особенно полезно
👉
👉
👉 conditional rendering
👉 enter animations в UI
Почему это ощущается приятно
Анимации становятся:
👉 чище
👉 предсказуемее
👉 без лишнего JS
В CSS появился
@starting-style.
Он решает старую проблему:
анимацию появления элемента,
который только что добавили в DOM.
Раньше для этого обычно:
👉 делали
setTimeout 👉 дёргали классы через JS
👉 ловили reflow-хаки
Теперь можно нативно:
.modal {
opacity: 1;
transition: opacity .2s;
}
@starting-style {
.modal {
opacity: 0;
}
}
Элемент появляется сразу с анимацией.
Без двойного рендера и JS-костылей.
Почему это важно
Раньше браузер не успевал увидеть
начальное состояние элемента.
Из-за этого приходилось:
👉 форсить reflow
👉 откладывать изменение класса
👉 городить лишнюю логику
Теперь CSS сам понимает:
👉 с какого состояния начинать transition
Где особенно полезно
👉
dialog 👉
popover 👉 conditional rendering
👉 enter animations в UI
Почему это ощущается приятно
Анимации становятся:
👉 чище
👉 предсказуемее
👉 без лишнего JS
CSS постепенно забирает себе всё,
что раньше приходилось городить через JavaScript.
👍31👎6😱3