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
更多关于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));
}
};
}