Архитектура фронтенда
Форма состояния: отрефакторь state-суп
Читать про ошибки формы — не то же самое, что распутывать их в реальном приложении. Собери (или возьми) дашборд «список + деталь» с фильтрами, чей state намеренно превращён в кашу — полученные данные в useState, хранимый count, фильтры, теряющиеся на рефреше, глобальный store, ререндерящий всё — и отрефакторь каждое значение в правильное место, доказывая выигрыш на каждом шаге.
Преврати дерево решений юнита в рабочий рефактор: классифицируй каждый кусок state, перенеси серверные данные в библиотеку кэша, шарящееся view-состояние в URL, приватный state вниз к нижнему читателю, удали выводимое и нормализуй реляционные данные, которые мутируешь — затем докажи меньше багов и меньше ререндеров.
Возьми дашборд со «state-супом» (свой или стартер ниже), где каждое значение лежит не там, и отрефакторь его так, чтобы каждый кусок state жил в правильной форме — server cache, URL, колоцированный клиентский state или derived — с измеримым доказательством, что багов drift и ререндеров стало меньше.
- Таблица инвентаризации state до/после, показывающая для каждого значения старый дом, новый дом и правило, его переместившее; ничего полученного не лежит в useState, ничего выводимого не хранится, а шарящееся view-состояние живёт в URL.
- Рефреш и копирование ссылки оба воспроизводят точный отфильтрованный/отсортированный/постраничный вид с той же открытой деталью — продемонстрировано, не предположено.
- Счётчик ререндеров (React DevTools Profiler или хук-логгер рендеров) до и после, показывающий, что ввод в фильтр или переключение меню больше не ререндерят несвязанные поддеревья вроде панели детали или графиков.
- Короткий разбор, объясняющий для каждого перенесённого значения, почему его новый дом верен и какой баг формы (drift, потеря view-состояния, шторм ререндеров, устаревший снимок) предотвращает перенос.
- Добавь оптимистичную мутацию (переименуй/отредактируй запись) через библиотеку кэша и покажи, что список, бейдж и открытая деталь остаются согласованными без ручного обновления count или копии.
- Замени ad-hoc парсинг query-строки на типизированный слой URL-состояния (маленькую обёртку useSearchParams или типизированные search-параметры роутера), чтобы фильтры безопасно round-trip-ились, а невалидные значения откатывались в дефолты.
- Добавь в CI проверку «shape lint», падающую, если полученный payload хранится в useState или если заведомо выводимое значение (count, total) появляется в state, чтобы суп не подкрался обратно.
- Измерь и отчитайся о сетевом выигрыше: подтверди, что два компонента-читателя теперь делают один общий запрос вместо двух и что смена фильтра рефетчит один раз с дедупом, а не по компоненту.
Это рефактор, который ты прогонишь на реальных кодовых базах: инвентаризируй каждое значение, затем направь каждое в правильный дом — полученные данные в server cache с ключом по запросу, шарящееся view-состояние в URL, приватный state вниз к нижнему читателю, выводимые значения удалены, а мутируемые реляционные данные нормализованы в byId-словарь. Доказательство конкретно: рефреш и скопированные ссылки воспроизводят вид, ререндеры сжимаются до владеющего поддерева, а баги drift становятся невозможны, потому что не осталось второго источника истины, который мог бы разойтись. Сделав это раз на игрушечном дашборде, ты превращаешь продакшен-распутывание в мышечную память.