Однонаправленный поток данных (unidirectional data flow) является фундаментальной концепцией архитектуры приложений, построенных на Hyperapp. Он обеспечивает предсказуемость состояния, упрощает отладку и повышает читаемость кода. В Hyperapp этот поток строится вокруг трёх ключевых элементов: state, actions и view.
state представляет собой единый источник истины для
всего приложения. Он описывает текущее состояние интерфейса и данных, с
которыми работает приложение. В Hyperapp state реализуется
как обычный JavaScript-объект:
const state = {
count: 0,
user: { name: "Alice", loggedIn: false },
todos: []
};
Ключевые моменты:
state происходят исключительно через действия
(actions).state из view осуществляется
напрямую, но изменение состояния происходит строго контролируемым
образом.actions — функции, которые описывают, как состояние
должно изменяться. Они принимают текущее состояние и аргументы,
возвращая новый объект состояния. Это обеспечивает чистоту и
предсказуемость изменений:
const actions = {
increment: state => ({ count: state.count + 1 }),
login: (state, payload) => ({ user: { ...state.user, loggedIn: true, name: payload.name } }),
addTodo: (state, payload) => ({ todos: [...state.todos, payload] })
};
Особенности:
state через actions
автоматически инициирует повторный рендер view.view — это функция, которая превращает текущее состояние
и действия в виртуальный DOM. Она не изменяет state
напрямую, а лишь описывает интерфейс:
const view = (state, actions) => (
h("div", {}, [
h("h1", {}, `Счет: ${state.count}`),
h("button", { onclick: () => actions.increment() }, "Увеличить"),
h("ul", {}, state.todos.map(todo => h("li", {}, todo)))
])
);
Важные моменты:
view является чистой функцией: одинаковые входные
данные дают одинаковый результат.state и actions как
параметры, что исключает побочные эффекты.actions автоматически
перерисовывает соответствующие части интерфейса.В Hyperapp поток данных строится строго по принципу:
state → view → действия пользователя → actions → новый state → view
Детали работы:
state.view преобразует
state в виртуальный DOM и отображает его на странице.actions.actions
возвращают новый объект state.Такой однонаправленный поток исключает непредсказуемые изменения интерфейса и обеспечивает лёгкую масштабируемость приложения.
actions, что облегчает отслеживание
ошибок.state.actions можно легко
тестировать как чистые функции без UI.Hyperapp поддерживает модульный подход, позволяя разделять
state и actions на отдельные модули для разных
частей приложения. При этом принцип однонаправленного потока
сохраняется:
const todosModule = {
state: { todos: [] },
actions: {
add: (state, payload) => ({ todos: [...state.todos, payload] })
}
};
const appState = { ...todosModule.state, count: 0 };
const appActions = { ...todosModule.actions, increment: state => ({ count: state.count + 1 }) };
Каждый модуль управляет своей частью состояния, но весь поток данных остаётся единым и предсказуемым.
Основные элементы, формирующие однонаправленный поток:
Следование этой архитектуре делает приложение устойчивым к ошибкам и легко расширяемым, независимо от его сложности.