Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Состояние приложения JS: Архитектура фронтенда

Манипулирование DOM — задача простая только в самых примитивных ситуациях. Как только понадобится реализовать полноценное (пусть и небольшое) приложение, код моментально превращается в тыкву. Десятка обработчиков достаточно для того, чтобы потеряться. С каждым новым событием сложность кода растёт ещё быстрее, а ведь в реальных приложениях событий сотни. Почему так происходит?

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

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

Из браузера в базу данных через приложение

По сути, в типичных веб-проектах приложение занимается двумя процессами: либо обновляет данные в базе, либо извлекает эти данные и на основе них формирует HTML. Необходимость базы данных довольно очевидна и понятна для всех, но то же самое не очевидно во фронтенде. DOM позволяет хранить состояние внутри себя и, более того, провоцирует так делать. На протяжении курса мы будем встречаться с этой ситуацией ещё не раз, когда нужно выполнить некоторое действие, а оно зависит от того, что сейчас на экране. Для работы с этими данными приходится обращаться к DOM.

See the Pen js_dom_state_in_dom by Hexlet (@hexlet) on CodePen.

Главная проблема такого подхода в отсутствии единого источника правды. Одни и те же данные, на одной странице, могут использоваться множество раз. Причем иногда по разному. Представьте себе ситуацию, в которой нужно вывести количество отображаемых статей на странице. Для того чтобы их посчитать, придется писать такой код:

// Каждая статья обозначается классом .article
const articles = document.querySelectorAll('.article');
articles.length; // количество статей

А если у нас часть статей выводится в одном блоке, а часть в другом? Тогда придется обращаться к каждому из этих блоков, чтобы собрать все статьи. Чем дальше мы будем фантазировать, тем больше сложностей возникнет с тем, как работать с этими данными: добавлять, обновлять и использовать. Глядя на код, невозможно легко понять, откуда брать данные. Кроме того, они сильно завязаны на конкретную структуру верстки.

Отделение состояния приложения

Первый шаг в построении правильной архитектуры состоит в выделении данных, которыми манипулирует приложение из DOM. Их необходимо выделить в отдельную переменную на уровне приложения (не на глобальном уровне! Каждый запуск приложения должен быть независим). Это позволит отделить работу с данными от их отображения.

При такой организации кода вырисовывается следующая схема работы:

  • Возникает событие
  • Обработчик события меняет состояние
  • DOM обновляется на основе новых данных

Ниже реализация этой идеи на примере простого счётчика. Состояние в данном случае — одно число. Кнопка с плюсом увеличивает его на единицу, кнопка с минусом соответственно уменьшает.

See the Pen js_dom_state_simple by Hexlet (@hexlet) on CodePen.

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


Дополнительные материалы

  1. Скрипты, модули и библиотеки
  2. Состояние в модулях

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
18 мая 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Новый
Разработка фронтенд и бэкенд компонентов веб-приложений
18 мая 16 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»