Конечно, он его не изобретал. Но если бы посмотрел сегодня сливы собесов, точно увидел бы в них свои идеи. Ведь есть же фундаментальные идеи за всей этой шелухой про синтаксис mapStateToProps!

Императивное программирование
Допустим, вам поручили сделать web проигрыватель. Бизнес ставит задачи, сроки горят. Что делаем? Правильно, берём родной <audio>.
<audio src="https://cdn.pixabay.com/audio/2025/03/18/audio_7d5c12b31a.mp3"></audio>
Нужно будет лишь подписаться на его события.
// Обработчики событий элемента <audio>
audio.addEventListener("play", () => {
// ...
});
audio.addEventListener("pause", () => {
// ...
});
audio.addEventListener("ended", () => {
// ...
});
// Обновление прогресса
audio.addEventListener("timeupdate", () => {
// ...
});
Самое интуитивное желание — определить четыре флага для каждого возможного состояния проигрывателя.
// Множество флагов состояния
var isPlaying = false;
var isPaused = false;
var isStopped = false;
var isEnded = false;
И на каждое событие проверить все флаги и выключить логически ненужные. В конце - перерисовать интерфейс.
audio.addEventListener("play", () => {
isPlaying = true;
isPaused = false;
isStopped = false;
isEnded = false;
updateUI();
});
Всё работает! Что ещё можно желать?
Ссылка на рабочий пример: https://jsbin.com/huyijutoyi/edit?js,output.
Автоматное программирование
Проблема с флагами в их необязательности. Может ли проигрыватель быть одновременно в isPlaying и isEnded? По логике — нет, но в коде ничто не мешает этому случиться.
В командной разработке нужно решение, которое сделает такие ошибки невозможными. Решение, которое облегчит жизнь не только программистам, но и бизнесу. И оно было придумано задолго до JavaScript — это конечные автоматы. Заметный вклад в объединение этой темы с программированием внёс Алан Тьюринг.
Вернёмся в воображаемую контору. Вот планы команды на ближайшее будущее:
Записывать действия пользователей
Поддерживать состояния: volumechange, waiting, emptied
Прислушаться к советам мудрого сторожилы конторы и использовать «design patterns» для разбиения на файлы
И всего через три итерации уже ясно, что следующая задача — документирование количества флагов и мест, где они могут меняться.
Нужно решение! Чтобы большая команда делала меньше ошибок.
Да и чтобы бизнес понимал какие состояния бывают и что умеет приложение.
Немного поискав информацию, можно найти прекрасные доклады и целую книгу:
Кирилл Мокевнин, Конечные автоматы как способ значительно упростить логику и понимание кода
"Автоматное программирование" Поликарпова Н. И., Шалыто А. А.
Александр Усков — Автоматное программирование и его применение в видеостриминге
Конечный автомат на React Hooks и Typescript — Сергей Володин
Решено! Будем использовать наследие Алана Тьюринга и его современников - использовать конечные автоматы.
Конечные автоматы
Посмотрим на схему работы, может что-то можно переписать иначе?

Нужно не улучшить текущий код, а переписать его заново (да, тоже нужно будет протолкнуть на планировании)!
Буквально, поменять эти флаги на состояние. Написать простую схему переходов между ними и запрограммировать с функцией-редуктором.

Благо, в воображаемом примере не всё так плохо. Можно легко переписать флаги на множество управляющих состояний.
// Множество управляющих состояний
var STATES = {
STOPPED: "⏹️ Остановлен",
PLAYING: "? Играет",
PAUSED: "⏸️ Пауза",
ENDED: "✅ Завершено",
};
А бизнес-логику приложения перенести из каждого события в функцию переходов (она же редуктор).
// Функция переходов
function handleAction(action) {
switch (action) {
case "PLAY":
if (currentState === STATES.STOPPED || currentState === STATES.PAUSED) {
audio.play();
currentState = STATES.PLAYING;
}
break;
case "PAUSE":
// ...
break;
case "STOP":
// ...
break;
}
updateUI();
}
Обновление интерфейса теперь простая задача: есть состояние - покажи сообщение.
И так мы переехали на автоматное программирование!
У нас есть единое управляющее состояние
Логика переходов единственно, полно и декларативно описана в функции переходов
Этот switch-case уже можно вынести в отдельную библиотеку!
Ссылка на рабочий пример: https://jsbin.com/kelukazovu/edit?js,output.
Redux
Так и сделаем! А потом, а потом…
Сделаем независимую от бизнес-логики библиотеку,
чтобы и в реакте работало,
чтобы и обновление частей состояния не вызывало перерисовки!!
Чтобы были плагины в браузере для истории переходов!
Постойте... нам что, нужен Redux?!
Конечно, для нашего такого проигрывателя — это стрельба из базуки по воробьям. Но главное – это фундаментальный принцип, на котором он построен.
Redux — это не просто магический и новомодный синтаксис с экосистемой. Это, в первую очередь, реализация архитектурного шаблона конечного автомата, дополненная удобными инструментами (middleware, dev-tools).
Ссылка на рабочий пример с Redux: https://jsbin.com/wazimaziga/edit?js,output.
Вывод
Так я показал проблему управления состоянием и её решения, начав аж с самого Тьюринга!
Я жалею, что никто не рассказывал мне про redux именно так. Большинство блогеров сразу переходят к синтаксису, не отвечая на вопрос: “оно вообще зачем нужно?”.
Так же я ранее рассмотрел и тему замыканий, начав с проблемы фунарга. И ещё много говорил про концепции React.
Если вы есть, будьте первыми!
Комментарии (5)

Arhammon
13.11.2025 08:55Вроде блок-схемы придумали для удобного восприятия процессов, а не для дизайнерских изысков...
Tzimie
Надо было начать с Рюрика
Alexandroppolus
Редукс существовал задолго до Рюрика, просто ещё не был открыт
gev
Еще в Древнем Риме! И уже потом его не Тьюринг, а Чёрч перепридумал для лямбда-исчисления!
Tzimie
Месье Платонист? Жму руку