Flutter实体状态管理插件redux_entity的使用

Flutter 实体状态管理插件 redux_entity 的使用

redux_entity 是一个用于在 Redux 存储中维护对象集合的工具。它旨在与 Angular 的优秀模块 @ngrx/entity 靠近匹配,主要修改点在于 TypeScript 和 Dart 之间的差异。

测试工具

如果你基于 RemoteEntityReducer 创建自己的减少器(reducer),确保良好的测试覆盖率可能会很费劲。你不仅需要测试减少器对你的自定义操作符的响应,还需要确保现有的功能继续正常工作。

为了简化这个过程,建议将以下文件复制到你的测试套件中:

// 远程实体减少器测试器

你可以使用这个测试器来测试当添加自定义操作时,现有的功能是否继续正常工作。

贡献

欢迎贡献!但是,

  • 本项目旨在达到生产就绪状态。没有附带测试的 PR 将不会被合并。
  • 我们希望促进健康、友好且包容的开发社区。因此,请阅读并同意遵守 行为准则

示例代码

下面是使用 redux_entity 的完整示例代码。

安装依赖

首先,在你的 pubspec.yaml 文件中添加 redux_entity 依赖:

dependencies:
  flutter:
    sdk: flutter
  redux:
  redux_entity:

然后运行 flutter pub get 来安装这些依赖。

定义实体模型

定义一个简单的实体类:

class User {
  final String id;
  final String name;

  User({required this.id, required this.name});

  // 重写 == 和 hashCode 方法,以便可以比较实体对象
  [@override](/user/override)
  bool operator ==(Object other) =>
      identical(this, other) ||
          other is User &&
              runtimeType == other.runtimeType &&
              id == other.id &&
              name == other.name;

  [@override](/user/override)
  int get hashCode => id.hashCode ^ name.hashCode;
}

创建 Redux Store

创建一个 Redux store 并使用 EntityReducer 管理用户实体:

import 'package:flutter/material.dart';
import 'package:redux/redux.dart';
import 'package:redux_entity/redux_entity.dart';

// 定义初始状态
final initialState = EntityState<User>();

// 创建 store
final store = Store<EntityState<User>>(
  EntityState.reducer,
  initialState: initialState,
);

定义 Action

定义一些基本的 action 用于管理用户实体:

// 添加用户
class AddUserAction {
  final User user;

  AddUserAction(this.user);
}

// 删除用户
class RemoveUserAction {
  final String userId;

  RemoveUserAction(this.userId);
}

创建 Reducer

创建一个处理这些 action 的 reducer:

EntityReducer<User> userReducer(EntityState<User> state, dynamic action) {
  if (action is AddUserAction) {
    return state.add(action.user);
  } else if (action is RemoveUserAction) {
    return state.removeWhere((user) => user.id == action.userId);
  }
  return state;
}

创建 UI 组件

创建一个 UI 组件,用于展示和操作用户列表:

class UserList extends StatelessWidget {
  final Store<EntityState<User>> store;

  UserList(this.store);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('用户列表')),
      body: Column(
        children: [
          ElevatedButton(
            onPressed: () {
              // 添加一个新用户
              store.dispatch(AddUserAction(User(id: '1', name: '张三')));
            },
            child: Text('添加用户'),
          ),
          Expanded(
            child: StreamBuilder<EntityState<User>>(
              stream: store.onChange,
              initialData: store.state,
              builder: (context, snapshot) {
                final users = snapshot.data!.items;
                return ListView.builder(
                  itemCount: users.length,
                  itemBuilder: (context, index) {
                    final user = users[index];
                    return ListTile(
                      title: Text(user.name),
                      trailing: IconButton(
                        icon: Icon(Icons.delete),
                        onPressed: () {
                          // 删除一个用户
                          store.dispatch(RemoveUserAction(user.id));
                        },
                      ),
                    );
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

主程序

最后,创建主程序来启动应用:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return StoreProvider<EntityState<User>>(
      store: store,
      child: MaterialApp(
        home: UserList(store),
      ),
    );
  }
}

更多关于Flutter实体状态管理插件redux_entity的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter实体状态管理插件redux_entity的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


redux_entity 是一个用于 Flutter 的状态管理插件,它结合了 Redux 和实体(Entity)的概念,特别适合管理复杂的数据实体(如用户、产品、订单等)。通过 redux_entity,你可以更高效地管理应用中的实体状态,并且保持代码的可维护性。

1. 安装依赖

首先,你需要在 pubspec.yaml 文件中添加 redux_entity 依赖:

dependencies:
  flutter:
    sdk: flutter
  redux_entity: ^0.1.0  # 请查看最新版本
  redux: ^5.0.0         # Redux 核心库
  flutter_redux: ^0.8.0 # Flutter 与 Redux 的集成库

然后运行 flutter pub get 来安装依赖。

2. 创建实体模型

假设你有一个 User 实体,你可以这样定义它:

class User {
  final String id;
  final String name;
  final String email;

  User({required this.id, required this.name, required this.email});

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is User && runtimeType == other.runtimeType && id == other.id;

  @override
  int get hashCode => id.hashCode;
}

3. 创建实体状态和 Redux Store

使用 redux_entity 来管理 User 实体的状态:

import 'package:redux_entity/redux_entity.dart';
import 'package:redux/redux.dart';

// 定义实体状态
typedef UserState = EntityState<User>;

// 创建 Redux Store
final store = Store<UserState>(
  entityReducer<User>(),
  initialState: UserState(),
);

4. 定义 Actions

定义一些操作实体的 Actions,例如添加、更新、删除用户:

class AddUserAction extends EntityAction<User> {
  final User user;

  AddUserAction(this.user);

  @override
  UserState reduce(UserState state) {
    return state.add(user);
  }
}

class UpdateUserAction extends EntityAction<User> {
  final User user;

  UpdateUserAction(this.user);

  @override
  UserState reduce(UserState state) {
    return state.update(user);
  }
}

class DeleteUserAction extends EntityAction<User> {
  final String userId;

  DeleteUserAction(this.userId);

  @override
  UserState reduce(UserState state) {
    return state.remove(userId);
  }
}

5. 连接 Redux Store 到 Flutter 应用

使用 flutter_redux 将 Redux Store 连接到 Flutter 应用:

import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StoreProvider(
      store: store,
      child: MaterialApp(
        home: UserListScreen(),
      ),
    );
  }
}

class UserListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('User List')),
      body: StoreConnector<UserState, List<User>>(
        converter: (store) => store.state.entities.values.toList(),
        builder: (context, users) {
          return ListView.builder(
            itemCount: users.length,
            itemBuilder: (context, index) {
              final user = users[index];
              return ListTile(
                title: Text(user.name),
                subtitle: Text(user.email),
              );
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 添加新用户
          store.dispatch(AddUserAction(User(
            id: '1',
            name: 'John Doe',
            email: 'john@example.com',
          )));
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

6. 处理异步操作

如果你的操作是异步的(例如从 API 获取数据),你可以使用 redux_thunk 中间件来处理:

dependencies:
  redux_thunk: ^0.4.0

然后在创建 Store 时添加中间件:

import 'package:redux_thunk/redux_thunk.dart';

final store = Store<UserState>(
  entityReducer<User>(),
  initialState: UserState(),
  middleware: [thunkMiddleware],
);

定义异步 Action:

ThunkAction<UserState> fetchUsers() {
  return (Store<UserState> store) async {
    // 模拟从 API 获取数据
    final users = await fetchUsersFromApi();
    for (var user in users) {
      store.dispatch(AddUserAction(user));
    }
  };
}
回到顶部