Разработка · 6 мин чтения

Что проверить в код-ревью React-проекта перед приёмкой

Код-ревью React-проекта перед приёмкой - это не пробежка глазами по diff в GitHub, а системная проверка архитектуры, состояния, производительности и безопасности кода. За несколько лет я принимал десятки CRM-панелей и SPA-сервисов на React, сделанных фрилансерами и аутсорс-командами, и почти всегда проблемы находятся не в синтаксисе, а в том, как разработчик обращается с состоянием и побочными эффектами. Ниже - чек-лист, по которому я сам прохожу код перед тем, как подписать акт приёмки или дать зелёный свет на мердж в прод.

Структура компонентов и архитектура React-проекта

Первое, на что смотрю, открыв репозиторий, - как разложены папки. Если в components лежит 120 файлов без деления на фичи или домены, это уже красный флаг: такой проект будет тяжело поддерживать через полгода, даже если сейчас всё работает. На CRM-панели для одного клиента я принимал именно такую структуру - все компоненты в одной плоской папке, включая формы заказов, виджеты аналитики и модалки настроек. Рефакторинг под feature-based структуру занял отдельные три дня работы, которые в бюджет проекта изначально не закладывались.

Смотрю на размер компонентов: если файл разросся за 300 строк и в нём смешаны разметка, бизнес-логика и запросы к API - это повод разбить его на кастомные хуки и презентационные компоненты. Отдельно проверяю, нет ли props drilling через четыре-пять уровней вложенности вместо Context или стейт-менеджера. Если пропсы прокидываются через компоненты, которые сами их не используют, а просто передают дальше, - это архитектурный долг, который со временем множит баги при рефакторинге.

Состояние, хуки и побочные эффекты в React-коде

Bольшинство реальных багов в React-проектах живёт в useEffect. Проверяю каждый эффект на три вещи: правильный массив зависимостей, cleanup-функцию там, где она нужна, и оправданность самого использования эффекта - часто разработчики тянут через useEffect то, что можно посчитать прямо при рендере через useMemo.

Пример из практики: в проекте с интеграцией через n8n данные заказов подтягивались в useEffect без AbortController и без очистки при размонтировании компонента. При быстром переключении фильтров это давало гонку запросов - интерфейс иногда показывал данные от предыдущего фильтра поверх актуальных. Рабочий вариант выглядит так:

useEffect(() => {
  const controller = new AbortController();

  fetchOrders(filterId, controller.signal)
    .then(setOrders)
    .catch((err) => {
      if (err.name !== 'AbortError') setError(err);
    });

  return () => controller.abort();
}, [filterId]);

Отдельно смотрю на выбор стейт-менеджера и на то, насколько он соответствует размеру проекта. Redux Toolkit на лендинге с тремя формами - это оверинжиниринг, который увеличивает время на онбординг нового разработчика. А голый useState с прокидыванием через семь компонентов на панели с 40 экранами - обратная крайность. Zustand или Context с useReducer чаще всего оказываются золотой серединой для проектов среднего размера.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Производительность: ре-рендеры, мемоизация и размер бандла

Проверяю производительность не через ощущения, а через React DevTools Profiler: смотрю, какие компоненты перерендериваются при простых действиях вроде ввода текста в поле поиска. Если весь список из 200 карточек товаров перерисовывается при каждом нажатии клавиши, потому что состояние поиска лежит в общем родителе без мемоизации дочерних элементов, - это конкретная и легко чинимая проблема.

На что смотрю по производительности:

  • React.memo на компонентах списков и карточек, которые рендерятся десятками
  • useMemo и useCallback не расставлены бездумно везде, а применяются там, где реально есть дорогие вычисления или стабильность ссылок важна для дочерних мемо-компонентов
  • Виртуализация длинных списков (react-window или аналог) для таблиц от нескольких сотен строк - актуально для дашбордов и админок
  • Код-сплиттинг через lazy и Suspense для маршрутов, которые не нужны на первом экране
  • Размер итогового бандла - прогоняю через source-map-explorer, чтобы найти случайно затянутые целиком библиотеки вроде lodash или moment

На одном из дашбордов с BI-виджетами на Vue.js в соседнем проекте разница между до и после виртуализации таблицы на 5000 строк была в буквальном смысле секунды загрузки против почти мгновенного рендера - тот же принцип применим и к React-таблицам без исключений.

Безопасность React-кода: XSS, секреты и запросы к API

Безопасность в код-ревью React-проекта проверяю по трём направлениям. Первое - использование dangerouslySetInnerHTML: если контент из CMS или пользовательского ввода вставляется без санитайзера вроде DOMPurify, это прямая дыра под XSS. Второе - секреты в коде: API-ключи для эквайринга или сторонних сервисов не должны попадать в клиентский бандл, только в переменные окружения на бэкенде или в серверные роуты. Видел случай, когда ключ от T‑Bank эквайринга оказался прямо в собранном JS-файле фронтенда - его можно было достать через обычный просмотр исходного кода в браузере.

Третье - обработка ответов от внешних API и виджетов. Если в форме заказа стоит интеграция с СДЭК для расчёта доставки, проверяю, что фронтенд не доверяет слепо ответу виджета и что расчёт стоимости валидируется на сервере перед оплатой - иначе через devtools можно подменить сумму заказа прямо в запросе. Отдельно смотрю на CORS-настройки и на то, не остались ли в проде дебажные эндпоинты или моковые данные, которые должны были уйти вместе с разработческим окружением.

Тесты и типизация - минимальный порог для приёмки

Не требую 100% покрытия тестами - это редко оправдано по срокам и бюджету. Но смотрю на то, покрыты ли тестами бизнес-критичные сценарии: оформление заказа, авторизация, расчёт суммы, отправка формы. Для React Testing Library проверяю, что тесты проверяют поведение через доступный интерфейс (getByRole, getByText), а не завязаны на детали реализации вроде классов или структуры DOM - иначе тесты будут ломаться при каждом косметическом рефакторинге и превратятся в обузу, а не в страховку.

По TypeScript смотрю на strict-режим в tsconfig и на количество any в кодовой базе - команда grep ‑r “any” src - include=*.tsx даёт быструю оценку. Десяток any в утилитах - нормально, полсотни any в бизнес-логике форм и запросов - сигнал, что типизация добавлена для галочки, а не для реальной защиты от ошибок. Также проверяю, что типы пропсов компонентов не дублируют интерфейсы API вручную, а генерируются или переиспользуются из единого источника, иначе типы и бэкенд быстро разъезжаются.

Чек-лист ревьюера: таблица по областям проверки

Собрал в таблицу то, с чего начинаю проверку каждого React-проекта перед приёмкой - удобно держать под рукой при первом проходе по репозиторию.

Область На что смотреть Красный флаг
Структура Деление по фичам, размер компонентов Плоская папка components на 100+ файлов
Состояние Зависимости useEffect, cleanup-функции Пустой массив зависимостей при реальных внешних значениях
Производительность Профилировщик, размер бандла Ре-рендер всего списка при вводе текста
Безопасность dangerouslySetInnerHTML, переменные окружения API-ключи в клиентском бандле
Тесты Покрытие критичных сценариев Тесты завязаны на CSS-классы вместо ролей
Типизация strict-режим, количество any any в основных бизнес-компонентах

Если по итогам ревью выясняется, что стейт-менеджмент и структура компонентов проще переписать заново, чем чинить точечно, - на этом же этапе стоит прикинуть, что дешевле: доработка текущей кодовой базы или заказ CRM-панели на React с нуля. Иногда правки растягиваются на недели и по итоговой стоимости обгоняют разработку с чистого листа.

Разобраться перед стартом

Консультация

от 3 000 ₽

Подробнее →

Частые вопросы

Сколько времени занимает полное код-ревью React-проекта среднего размера

Для панели на 40-60 компонентов с базовой бизнес-логикой закладываю от 4 до 8 часов на первый проход: структура, хуки, производительность, безопасность. Если находятся системные проблемы вроде отсутствия типизации или тестов на критичных сценариях, повторный детальный разбор конкретных модулей добавляет ещё несколько часов.

Нужно ли требовать 100% покрытие тестами перед приёмкой

Нет, для большинства коммерческих проектов это избыточно и не окупается по срокам. Важнее покрыть бизнес-критичные сценарии - оплату, авторизацию, отправку форм - чем гнаться за процентом покрытия ради цифры в отчёте.

Что делать, если ревью выявило серьёзные архитектурные проблемы уже после приёмки

Фиксирую конкретные находки с примерами кода и оцениваю трудозатраты на исправление отдельно от исходного техзадания - это отдельная работа, которую нужно обсуждать как доработку, а не как гарантийный случай, если проблема не была прописана в критериях приёмки изначально.

Можно ли провести код-ревью без доступа к репозиторию, только по демо-версии

Частично - по демо оцениваются производительность и заметные баги в поведении интерфейса, но структуру компонентов, состояние и безопасность кода без доступа к исходникам проверить нельзя. Для полноценного ревью нужен хотя бы read-only доступ к репозиторию.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Самозанятый Калинкин Н. А. · работаю с физлицами и юрлицами

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно