首页 > 解决方案 > 使用 async_redux 进行嵌套状态的减速器

问题描述

我正在为 Flutter 尝试 async_redux,并且喜欢嵌套状态的想法。

我有一个这样的 AppState:

class AppState {
  final LoginState loginState;

  AppState({this.loginState});

  AppState copy({LoginState loginState}) {
    return AppState(
      loginState: loginState ?? this.loginState,
    );
  }

...

还有我的登录状态:

class LoginState {
  final bool isLoggedIn;

  LoginState({this.isLoggedIn});

  LoginState copy({bool isLoggedIn}) {
    return LoginState(isLoggedIn: isLoggedIn ?? this.isLoggedIn);
  }

...

但是如何让我的 reducer 更新我的 LoginState 中的 isLoggedIn?我已经尝试了一些东西,但没有得到任何地方。这显然是行不通的,但只是为了给出一个起点:

class LoginAction extends ReduxAction {

  final String username;
  final String password;

  LoginAction({this.username, this.password}) : assert(username != null && password != null);

  @override
  AppState reduce() {
    return state.copy(loginState: state.loginState.isLoggedIn = true);
  }
}

有任何想法吗?


谢谢索伦_

标签: flutterdartreduxasync-redux

解决方案


登录过程是异步的,因此您可能应该这样做Future<AppState> reduce()而不是AppState reduce().

然后你必须运行你的登录代码并返回一个布尔值,说明用户现在是否登录:bool result = await logIn(username, password);

如果不成功,抛出一个用户异常:if (!done) throw UserException("Please check your username and password.");

此时,使用更改重新创建状态:

class LoginAction extends ReduxAction {

  final String username;
  final String password;

  LoginAction({this.username, this.password}) :
     assert(username != null && password != null);

  @override
  Future<AppState> reduce() {
    if (state.loginState.isLoggedIn) throw UserException("You are already logged in.");

    bool done = await logIn(username, password);

    if (!done) throw UserException("Please check your username and password.");

    return state.copy(
              loginState: state.loginState.copy(isLoggedIn: true),
    );
  }
}

推荐阅读