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

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

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

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

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

Автоматное программирование

Тема конечных автоматов занимает центральную роль во фронтенд-разработке. Интерактивные элементы всегда вовлечены в процессы, связанные с изменением состояний. Модальные окна бывают открытые и скрытые, кнопка нажата, отжата или заблокирована (например, во время AJAX-запроса). Примеров бесконечное множество. Нередко эти автоматы зависят друг от друга, что порождает иерархию автоматов. Например, возможность взаимодействовать с элементом на экране может появляться только после нажатия кнопки "редактировать".

В React работа с автоматами проста до безобразия и в большинстве случаев не требует использования специальных библиотек. Возьмём, к примеру, кнопку, которая отвечает за показ куска текста. Её состояния можно описать так:

  • По умолчанию текст скрыт (состояние hidden).
  • Клик по кнопке отображает текст (состояние shown).
  • Повторный клик прячет текст (hidden).

В данном случае у кнопки два состояния, поэтому можно упростить задачу и использовать флаг как индикатор состояния. Назовём его как isShown.

Я очень не рекомендую так делать в бэкенде, когда состояние хранится в базе. Цена изменения автомата слишком высока (изменение типа колонки с boolean на string), поэтому даже в случае бинарной логики лучше делать полноценный автомат с именованными состояниями. Другими словами, для хранения состояния используйте не булево поле (с true/false), а текстовое поле, в котором будет содержаться полное название состояния. Например, если статья может находиться в двух состояниях ("опубликована" или "не опубликована"), то нужно делать не поле 'published: bool' со значениями true и false, а поле 'publishing_state' со значениями 'published' и 'unpublished'`

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

Большая часть кода в React (как и во всем фронтенде) выглядит именно так, как в примере выше. События порождают изменения состояния в данных, на основе которых, в свою очередь, меняется представление. Количество конечных автоматов во фронтенд-приложениях растёт с астрономической скоростью, главное их видеть и выделять явно.

Структура состояния

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

Если предположить, что данные, пришедшие с бэкенда, внутри нашего объекта-состояния хранятся как список под ключом items, то возникает вопрос: куда записывать данные, отвечающие за состояние UI? То есть те самые состояния, которые появляются только при взаимодействии с пользователем и не используются на серверной стороне?

Поясню на примере. К нам приходит статья такой структуры: { id: 3, name: 'How to program', state: 'published' }. Мы отправляем её в items. А в UI есть возможность зайти в её редактирование и для этого используется флаг (состояние) isEditing, который существует только на экране. Вопрос: где хранить эту переменную?

Самый простой вариант: изменить саму статью внутри items так, чтобы она имела такой вид: { id: 3, name: 'How to program', state: 'published', isEditing: true }. Хотя на первый взгляд он и кажется разумным, проблем он привносит больше, чем пользы. В основном эти проблемы связаны с задачами синхронизации. Иногда бывает нужно отправить всю статью на сервер (после изменений), а иногда перечитать её заново с бэкенда. В такой ситуации нужно будет либо извлекать только нужные данные, либо постоянно делать "мердж" (слияние), чтобы не потерять состояние UI. Практика показала, что гораздо проще добавлять отдельный список исключительно под задачи хранения состояния UI. То есть в нашем стейте появится список под названием itemUIStates, и для нашей статьи в него добавится элемент { articleId: 3, isEditing: true }.


<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

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

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

Для полного доступа к курсу нужна профессиональная подписка

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

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Зарегистрироваться

или войти в аккаунт

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

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

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

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

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

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

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