AsyncRedux同步动作开发Skill asyncredux-sync-actions

该技能用于在 Flutter 应用中实现同步状态管理动作,通过 AsyncRedux 库定义 ReduxAction 子类,使用 reduce() 方法返回新状态以立即更新应用状态。关键词:AsyncRedux, Flutter, 同步动作, 状态管理, Redux, 移动开发。

移动开发 0 次安装 0 次浏览 更新于 3/19/2026

name: asyncredux-sync-actions description: 创建 AsyncRedux (Flutter) 同步动作,通过实现 reduce() 方法返回新状态,立即更新状态。

AsyncRedux 同步动作

基本同步动作结构

同步动作从其 reduce() 方法返回 AppState?。动作立即完成,状态立即更新。

class Increment extends ReduxAction<AppState> {
  @override
  AppState? reduce() => state.copy(counter: state.counter + 1);
}

关键组件

扩展 ReduxAction

每个动作扩展 ReduxAction<AppState>

class MyAction extends ReduxAction<AppState> {
  @override
  AppState? reduce() {
    // 返回新状态
  }
}

state Getter

reduce() 中,通过 state getter 访问当前状态:

class ToggleFlag extends ReduxAction<AppState> {
  @override
  AppState? reduce() => state.copy(flag: !state.flag);
}

通过构造函数传递参数

通过构造函数字段将数据传递给动作:

class SetName extends ReduxAction<AppState> {
  final String name;
  SetName(this.name);

  @override
  AppState? reduce() => state.copy(name: name);
}

class IncrementBy extends ReduxAction<AppState> {
  final int amount;
  IncrementBy({required this.amount});

  @override
  AppState? reduce() => state.copy(counter: state.counter + amount);
}

修改嵌套状态

对于嵌套状态对象,首先创建新的嵌套对象:

class UpdateUserName extends ReduxAction<AppState> {
  final String name;
  UpdateUserName(this.name);

  @override
  AppState? reduce() {
    var newUser = state.user.copy(name: name);
    return state.copy(user: newUser);
  }
}

分发同步动作

从 Widgets 中

使用上下文扩展:

// 触发并忘记
context.dispatch(Increment());

// 带参数
context.dispatch(SetName('Alice'));
context.dispatch(IncrementBy(amount: 5));

立即状态更新

同步动作立即更新状态:

print(store.state.counter); // 2
store.dispatch(IncrementBy(amount: 3));
print(store.state.counter); // 5

使用 dispatchSync() 保证同步

dispatchSync() 如果动作是异步的,则抛出 StoreException。否则,它的行为与 dispatch() 完全相同。

仅当您必须确保动作是同步的,因为需要在分发返回后立即应用状态时,使用 dispatchSync()

context.dispatchSync(Increment());

从其他动作中

动作可以分发其他动作:

class ResetAndIncrement extends ReduxAction<AppState> {
  @override
  AppState? reduce() {
    dispatch(Reset());
    dispatch(Increment());
    return null; // 这个动作本身不改变状态
  }
}

返回 Null(无状态变化)

当不需要改变状态时,返回 null

class LogCurrentState extends ReduxAction<AppState> {
  @override
  AppState? reduce() {
    print('当前计数器:${state.counter}');
    return null; // 无状态变化
  }
}

条件状态变化:

class IncrementIfPositive extends ReduxAction<AppState> {
  final int amount;
  IncrementIfPositive(this.amount);

  @override
  AppState? reduce() {
    if (amount <= 0) return null;
    return state.copy(counter: state.counter + amount);
  }
}

使用基类简化动作

创建一个基动作类以减少样板代码:

// 定义一次
abstract class AppAction extends ReduxAction<AppState> {}

// 到处使用
class Increment extends AppAction {
  @override
  AppState? reduce() => state.copy(counter: state.counter + 1);
}

class SetName extends AppAction {
  final String name;
  SetName(this.name);

  @override
  AppState? reduce() => state.copy(name: name);
}

您可以为基类添加共享功能:

abstract class AppAction extends ReduxAction<AppState> {
  // 状态部分的快捷方式
  User get user => state.user;
  Settings get settings => state.settings;
}

class UpdateEmail extends AppAction {
  final String email;
  UpdateEmail(this.email);

  @override
  AppState? reduce() => state.copy(
    user: user.copy(email: email), // 使用快捷方式
  );
}

返回类型警告

reduce() 方法签名是 FutureOr<AppState?>。对于同步动作,始终直接返回 AppState?

// 正确 - 同步动作
AppState? reduce() => state.copy(counter: state.counter + 1);

// 错误 - 不要直接返回 FutureOr
FutureOr<AppState?> reduce() => state.copy(counter: state.counter + 1);

如果您直接返回 FutureOr<AppState?>,AsyncRedux 无法确定动作是同步还是异步,将抛出 StoreException

完整示例

// 状态
class AppState {
  final int counter;
  final String name;

  AppState({required this.counter, required this.name});

  static AppState initialState() => AppState(counter: 0, name: '');

  AppState copy({int? counter, String? name}) => AppState(
    counter: counter ?? this.counter,
    name: name ?? this.name,
  );
}

// 基动作
abstract class AppAction extends ReduxAction<AppState> {}

// 同步动作
class Increment extends AppAction {
  @override
  AppState? reduce() => state.copy(counter: state.counter + 1);
}

class Decrement extends AppAction {
  @override
  AppState? reduce() => state.copy(counter: state.counter - 1);
}

class IncrementBy extends AppAction {
  final int amount;
  IncrementBy(this.amount);

  @override
  AppState? reduce() => state.copy(counter: state.counter + amount);
}

class SetName extends AppAction {
  final String name;
  SetName(this.name);

  @override
  AppState? reduce() => state.copy(name: name);
}

class Reset extends AppAction {
  @override
  AppState? reduce() => AppState.initialState();
}

// 在 widget 中使用
ElevatedButton(
  onPressed: () => context.dispatch(IncrementBy(5)),
  child: Text('Add 5'),
)

参考

文档中的 URL: