Ответ
В архитектуре MVI (Model-View-Intent) Action (или Intent) — это иммутабельный объект-сообщение, который описывает намерение пользователя или системы изменить состояние приложения. Это единственный способ для View инициировать изменения.
Роль в однонаправленном потоке данных:
- View наблюдает за пользовательскими событиями (клики, ввод) и преобразует их в объекты
Action. - Intent (или обработчик) принимает поток Actions, применяет к ним необходимую бизнес-логику (например, асинхронные запросы) и выдает новые намерения для изменения Model.
- Model (состояние) обновляется на основе этих намерений, и новое состояние передается обратно во View для рендеринга.
Пример реализации на C# (упрощенно):
// 1. Определяем Actions как типы (часто используют record или sealed class)
public abstract record CounterAction;
public record IncrementAction(int Step = 1) : CounterAction;
public record DecrementAction(int Step = 1) : CounterAction;
public record LoadDataAction : CounterAction;
// 2. Модель (состояние)
public record CounterState(int CurrentCount, bool IsLoading);
// 3. Обработчик (Intent/Reducer), который создает новое состояние на основе Action
public static CounterState Reduce(CounterState currentState, CounterAction action)
{
return action switch
{
IncrementAction inc => currentState with { CurrentCount = currentState.CurrentCount + inc.Step },
DecrementAction dec => currentState with { CurrentCount = currentState.CurrentCount - dec.Step },
LoadDataAction => currentState with { IsLoading = true },
_ => currentState // Игнорируем неизвестные действия или возвращаем текущее состояние
};
}
Ключевые принципы для Action в MVI:
- Иммутабельность: Каждый Action — это неизменяемый "пакет" данных.
- Детерминированность: Для одного и того же Action и текущего состояния результат должен быть предсказуем.
- Серийность: Actions обрабатываются последовательно, что упрощает отладку и воспроизведение состояния.
- Отсутствие побочных эффектов: Сами Actions не содержат логики. Побочные эффекты (запросы к API) обрабатываются отдельно (например, в Middleware или сайд-эффект менеджере).
Ответ 18+ 🔞
Слушай, вот объясняю про MVI, как будто это не архитектура, а пиздёж в баре после пятой рюмки. Action — это, блядь, такая бумажка с заявлением: «Хочу, чтобы в приложении вот это поменялось!». Представь, ты в ЖЭКе стоишь — тебе надо окно поменять. Ты не лезешь сам с молотком, а пишешь заёб: «Уважаемые, в квартире 322 окно разъёбано, сделайте что-нибудь». Вот этот заёб и есть Action.
В MVI всё по понятиям работает:
- View — это ты, мудак, который тыкает в экран. Нажал кнопку — сразу пишешь заявление (Action): «Хочу, чтобы счётчик увеличился».
- Intent (или редьюсер) — это такой бюрократ-обработчик, который получает твоё заявление и говорит: «Ага, понял, ща сделаем». Он может сам позвонить куда надо (сделать запрос к API), но само заявление не меняет — он только на его основе решает, как поменять состояние (Model).
- Model — это, сука, реальное состояние дел в квартире. Окно было разбито, стало целое. После того как бюрократ обработал твой Action, состояние меняется, и View говорит: «О, окно починили, теперь можно не мёрзнуть».
Вот тебе пример на C#, чтоб вообще всё стало ясно, как божий день:
// 1. Action — это типы заявлений. Делаем их на record'ах, они иммутабельные, как мёртвый ёж.
public abstract record CounterAction;
public record IncrementAction(int Step = 1) : CounterAction;
public record DecrementAction(int Step = 1) : CounterAction;
public record LoadDataAction : CounterAction;
// 2. Model — состояние, которое все наблюдают.
public record CounterState(int CurrentCount, bool IsLoading);
// 3. Редьюсер — тот самый бюрократ, который решает, что делать с заявлением.
public static CounterState Reduce(CounterState currentState, CounterAction action)
{
return action switch
{
IncrementAction inc => currentState with { CurrentCount = currentState.CurrentCount + inc.Step },
DecrementAction dec => currentState with { CurrentCount = currentState.CurrentCount - dec.Step },
LoadDataAction => currentState with { IsLoading = true },
_ => currentState // Если заявление непонятное — игнорируем, хуй с ним.
};
}
А теперь, блядь, главные правила, чтобы не обосраться с Actions:
- Иммутабельность — твоё заявление нельзя подтереть или переписать. Отправил и всё. Хуй поменяешь.
- Детерминированность — один и тот же Action при одном и том же состоянии даёт одинаковый результат. Не должно быть: «Ой, сегодня пятница, поэтому +1, а в субботу — хуй знает что».
- Серийность — заявления обрабатываются по очереди, как в нормальной очереди в туалет. Нельзя вписаться без очереди — так проще отлаживать.
- Без побочки — в самом Action не должно быть логики, типа «пойти запросить данные с сервера». Это отдельная история, для этого есть сайд-эффекты, которые обрабатываются где-то рядом, но не в самом заявлении.
Короче, Action — это просто бумажка, констатация факта: «Я, пользователь, нажал сюда. Ваше дело решать, что делать дальше». Вся магия происходит в обработчике. Если держать эту дисциплину, то код живёт долго и счастливо, а если нет — получается пиздец, который потом разгребать, как говно за слоном.