Главная / Статьи

Почему фронтенд становится сложным после React: состояние, эффекты, границы и инструменты ИИ

React сделал создание интерфейсов пользовательского интерфейса проще, но не их проектирование. Там, где находится состояние, возникают запутанные эффекты, проблемы с границами системы и код, сгенерированный ИИ — вот что действительно требует усилий при разработке фронтенда.

Издатель: REACTAPP.TOP9 мин чтения2114 слов

Источники: React Isn’t the Hardest Part of Frontend Development

Некоторые разработчики фронтенда могут создать компонент на React за двадцать минут, а затем тратить следующие три часа на попытки понять, почему его стало невозможно поддерживать. Вина не в JSX, не в useState, и даже не в самом React. Проблемы возникают из-за всего того, что окружает фреймворк: необходимости понимания того, как должен вести себя продукт, выбора места хранения состояния, координации асинхронных вызовов, определения границ компонентов, справления с особенностями браузеров, обеспечения доступности и скорости интерфейсов, а также создания кода, который останется понятным даже через полгода.

React облегчил создание интерфейсов. Однако он никогда не делал инженерию фронтенда проще, и эта область слишком долго вела себя так, будто это так и есть.

Что исправил React, а что оставил без изменений

До появления React сложности были совершенно иного рода. Разработчики вручную редактировали DOM и по одному подключали обработчики событий, сталкиваясь с трудностями при синхронизации отображения с данными приложения. По мере роста приложений становилось всё сложнее отслеживать взаимосвязь между действиями пользователя, данными и отрисованными элементами.

React предложил полезную концепцию: интерфейс — это функция состояния. Вместо того чтобы указывать браузеру на каждое изменение DOM, достаточно описать, как будет выглядеть интерфейс при определённом состоянии. Компоненты определяют границы, атрибуты передают необходимые данные, состояние отражает информацию, которая меняется со временем, а декларативная отрисовка устраняет множество ненужных сложностей. Это действительно стало значительным шагом вперёд.

Тем не менее фреймворк решает только те проблемы, для которых он и был создан. React не имеет мнения о том, нужно ли приложению пять или пятьдесят элементов глобального состояния. Он не скажет, когда компонент выполняет слишком много функций, разумно ли проектирование API, находятся ли индикаторы загрузки в правильных местах или имеет ли смысл процесс оформления покупки для покупателя. К тому же он определенно не может решить, что должен делать продукт, когда соединение прерывается в процессе запроса. Все это также является проблемами фронтенда.

Обычная функция сталкивается с реальностью

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

Теперь опишем, что на самом деле происходит. Первый запрос терпит неудачу. Фильтр меняется, пока предыдущий запрос ещё в процессе обработки, и старый ответ приходит после нового. Модальное окно открывается по глубокой ссылке. Страница обновляется во время редактирования. Открыты два вкладки. Сессия истекает. API возвращает частичные данные. Сервер принимает изменения, но клиент так и не видит ответа, а пользователь нажимает кнопку сохранения дважды. В списке 10 000 строк, соединение медленное и через мобильное устройство, интерфейс должен работать с клавиатуры, а сообщение об ошибке должно указать, что делать дальше.

На этом этапе код на React — самая менее интересная часть. Всё это можно создать с помощью React, и всё это можно сделать плохо. Многие разработчики упускают эту разницу.

Задача — управление сложностью

Работа фронтенд-разработчика заключается не столько в написании компонентов, сколько в управлении сложностью, чтобы пользователь видел простой интерфейс, что гораздо сложнее. Хорошо написанный компонент может содержать пятьдесят строк кода, но добраться до этого числа, а не до пятисот, требует ряда решений:

  • Откуда берутся данные, кто за ними отвечает, как долго они существуют и кто может их изменить
  • Что происходит, если запрос не удался
  • Должен ли состояние сохраняться после навигации или обновления страницы
  • Следует ли хранить его в URL, в локальном состоянии компонента или в кэше сервера
  • Должны ли два компонента делиться самими данными или вычислять похожие значения самостоятельно

React не отвечает ни на один из этих вопросов. Разработчик отвечает, и ответы накапливаются. Слабое решение редко остается в пределах одного компонента — оно превращается в шаблон, другие разработчики копируют его, и вскоре у приложения появляется единая архитектура, которую никто не выбирал. Именно так кодовые базы фронтенда становятся проблематичными: решения накапливаются, причем сложность React тут играет второстепенную роль.

Состояние как проблема моделирования

Быстрый способ выявить незрелый дизайн фронтенда — посмотреть на его состояние. Чрезмерное использование useState само по себе не является ошибкой. Проблема в том, что состояние рассматривается как место для хранения значений, а не как объект, который нужно моделировать. Разработчик видит изменяющееся значение и сразу обращается к соответствующему хуку.

const [value, setValue] = useState(...)

Кажется, что всё готово, но настоящий вопрос не в том, как сохранить значение. Вопрос в том, должно ли это значение вообще существовать. Посмотрите на эту троицу:

const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [fullName, setFullName] = useState("");

В настоящее время три состояния хранят информацию, которую можно было бы получить из двух. Вина здесь не в React — ваших представлений о структуре данных.

То же самое происходит в масштабе: команды хранят ответы API, отфильтрованные копии этих ответов, флаги загрузки, рассчитанные показатели, выбранные записи, флаги модальных окон и дублированные версии одной сущности в нескольких местах. Со временем никто не может сказать, какая копия является авторитетной, и появляются ошибки — один компонент изменяет копию, в то время как другой читает другую. Эффект синхронизации пытается привести их в соответствие, а другой эффект реагирует на первый. Внезапно браузер превращается в небольшую распределенную систему. Эту архитектуру не создавал React — её создали те, кто пишет код.

Эффекты раскрывают структуру проекта

Если какая-то функция React привлекает к себе больше критики, чем остальные, это useEffect, и эта критика часто обоснована. Однако именно здесь обычно проявляются архитектурные проблемы, а не возникают они.

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

Это не недостаток React. Проблема в нечетком распределении ответственности и запутанных побочных эффектах, а React просто предоставляет место для их реализации.

Браузер — это лишь один узел в более крупной системе

Область разработки фронтенда постоянно расширяется. Современные приложения взаимодействуют с API и базами данных, системами аутентификации и аналитикой, а также с инструментами управления функциями, поставщиками платежей и другими сервисами сторонних разработчиков. К этому добавляются функции на краевых узлах, серверные компоненты, фоновые задачи, а также все чаще сервисы, основанные на ИИ. Браузер является лишь одним из участников гораздо более масштабной системы, поэтому разработчику фронтенда необходимо понимать не только процесс отрисовки, но и то, что происходит до и после того, как запрос покидает страницу.

Это не означает, что каждый должен стать специалистом по бэкенду. Это означает, что старое разделение на фронтенд и бэкенд становится менее полезным. Человек, который не знает HTTP, в конечном итоге будет сталкиваться с проблемами кэширования. Тот, кто не знаком с базами данных, будет испытывать трудности с пониманием принципов целостности данных, а тот, кто не разбирается в механизмах аутентификации, будет сталкиваться с проблемами, связанными с работой сессий. Условия соревнования и необходимость повторных попыток сбивают с толку разработчиков, не имеющих опыта работы с распределёнными системами, а те, кто не понимает потребностей пользователей, создают красивые интерфейсы, которые никому не нравятся. Фреймворк представляет собой единый слой.

Искусственный интеллект меняет экономику, но не сложные аспекты разработки

Ассистенты для программирования на основе ИИ изменили стоимость работы над фронтендом. Создание компонентов, форм, преобразование дизайна в JSX, использование хуков и тестирование стали дешевле. Это может показаться угрозой, но лучше рассматривать это как проверку того, где на самом деле заключается ценность. Если ваш основной вклад — быстрое вводение кода JSX, то ИИ представляет собой проблему. Если же ваша сила — понимание систем, архитектуры, поведения продукта, компромиссов и потребителей, то ИИ изменяет ваш рабочий процесс, оставляя сложные задачи без изменений и, вероятно, повышая их значимость.

Ассистент может за секунды подготовить три правдоподобных варианта реализации функции. Выбор между ними — это вопрос архитектуры, а не синтаксиса. Он может создать структуру управления состоянием, но должно ли это состояние быть глобальным? Он может написать код для оптимистичного обновления, но действительно ли приложение должно вести себя оптимистично? Он может добавить кэш, но какова стратегия его аннулирования? Он может написать код для обработки эффектов, но должен ли такой эффект вообще существовать? Чем быстрее появляется код, тем больше необходимо критического мышления, и именно это, скорее всего, будет определять работу над фронтендом в ближайшие годы.

Квалифицированные разработчики фронтенда склонны меньше думать о React и больше — о границах ответственности. Они задаются вопросом, кому принадлежит ответственность, и замечают, когда компонент превращается в небольшое приложение. Они борются с дублированием состояния, планируют сценарии сбоев ещё до успешного выполнения операций, знают, что на самом деле гарантирует API, и уделяют внимание неожиданному поведению пользователей. Они могут определить, когда абстракция полезна, а когда лишь скрывает сложность. Они понимают работу браузера, настраивают производительность, не оптимизируя всё преждевременно, и, что самое важное, могут объяснить, почему система работает именно так. Это намного сложнее навык для автоматизации и сохраняется дольше, чем знание новейшего API React.

Знания фреймворка устаревают

Разработчики недостаточно обсуждают этот вопрос: знания фреймворков имеют срок годности. API React, изученный пять лет назад, уже не совсем актуален сегодня. Лучшие практики меняются, библиотеки исчезают, инструменты сборки обновляются, стратегии отрисовки развиваются, возможности сервера расширяются, появляются новые фреймворки. Синтаксис меняется, но основные инженерные проблемы остаются практически неизменными:

  • Моделирование состояния и передача данных внутри системы
  • Обработка сбоев и управление асинхронной работой
  • Избегание ненужной связности
  • Создание системы, которую можно наблюдать, и интерфейса, к которому легко получить доступ
  • Контроль сложности

Эти проблемы пережили jQuery, Angular и Backbone, а также раннюю экосистему React. Они переживут и всё, что появится в будущем. Поэтому изучение фронтенда исключительно через фреймворки — это хрупкий подход. Изучайте фреймворк, но не путайте его с самой дисциплиной.

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

React — это инструмент, а не методология

Разработка фронтенда никогда не была связана исключительно с React. React — это очень хороший инструмент для создания фронтенд-приложений, и он по-прежнему остаётся инструментом. Самая сложная часть — это решение вопроса о том, что именно нужно реализовать: как взаимодействуют компоненты, что происходит при сбоях, где находится состояние, что выполняется в браузере и что — на сервере, как система развивается вместе с продуктом и как скрыть всё это от пользователя. Вот в чём заключается задача, а JSX — это лишь способ оформления части кода.

По мере того как инструменты становятся всё лучше в создании кода, его написание теряет на ценности. Однако это не приводит к завершению разработки программного обеспечения, хотя и меняет то, над чем должны размышлять разработчики. Человек, способный быстро сгенерировать компонент, полезен, но ещё более ценен тот, кто может оценить, действительно ли он необходим. То же самое касается интеграций API: их создание полезно, но способность заметить ошибку в самом контракте имеет ещё большую ценность. Разработчик, который может попросить ИИ переработать кодовую базу, имеет определённую ценность, а тот, кто может определить, улучшает ли предлагаемая переработка систему, — ещё большую.

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

Связанные материалы

  • Тестирование GLM 5.2 в Claude Code с использованием настоящего SDK за пять долларов — Эксперимент с OpenRouter стоимостью пять долларов: направление трафика из Claude Code в GLM 5.2, аудит и модификация SDK для React Native, стоимость каждого этапа работы и предел экономии.
  • Добавление экрана загрузки в приложение React Native для iOS и Android — Пошаговая настройка экрана загрузки для React Native на iOS и Android: экран запуска в Xcode, темы и макеты для Android, а также использование библиотеки react-native-splash-screen для устранения белого всплеска экрана.
  • React по-прежнему побеждает, но разработка на JavaScript меняется — React по-прежнему лидирует по уровню использования, однако современные подходы к его применению включают TypeScript, серверную отрисовку, инструменты сборки, улучшение производительности и использование ИИ. Вот что стоит изучить дальше.
  • 30 полезных советов по React и Redux для создания масштабируемых и легко обслуживаемых фронтендов — Тридцать кратких советов по React и Redux, касающихся управления состоянием, работы с серверными данными, использования хуков, селекторов, структуры папок, тестирования и рефакторинга, предназначенных для приложений с более чем тысячей компонентов.