Flutter状态管理插件redux_compact的使用
Flutter状态管理插件redux_compact的使用
Redux Compact
Redux Compact 是一个旨在减少维护 Flutter Redux 应用程序时大量样板代码的库。该库提供了一组中间件和一个 reducer,用于拦截一种特殊的动作称为 Compact Action。这种动作可以直接访问状态,并且可以是同步或异步的,同时提供了链式调用动作的能力。动作的 reducer 是一个名为 reduce
的方法,允许你在动作本身中进行相应状态的更改。
这种方法消除了维护单独的动作和 reducer 文件夹以及创建和分发多个动作来处理异步状态的需要。
使用方法
前提条件
本文档假设你已经熟悉 Redux 和 Flutter Redux,并了解它们的核心概念、设置和使用方法。
示例代码
初始化 Store
首先,按照 Flutter Redux 的推荐方式创建你的 Store,并添加 Redux Compact 中间件和 reducer。
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';
import 'package:redux_compact/redux_compact.dart';
void main() {
final compactReducer = ReduxCompact.createReducer<int>();
final compactMiddleware = ReduxCompact.createMiddleware<int>();
final store = Store<int>(
compactReducer, // 添加 compactReducer
initialState: 0,
middleware: [
compactMiddleware, // 添加 compactMiddleware
],
);
runApp(MyApp(
store: store,
title: "Redux Compact",
));
}
class MyApp extends StatelessWidget {
final Store<int> store;
final String title;
const MyApp({Key? key, required this.store, required this.title})
: super(key: key);
@override
Widget build(BuildContext context) {
return StoreProvider<int>(
store: store,
child: MaterialApp(
title: title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: CounterWidget(),
),
);
}
}
定义 Compact Action
然后,定义一个扩展 CompactAction
的动作并分发它。
class IncrementCountAction extends CompactAction<int> {
final int incrementBy;
IncrementCountAction(this.incrementBy);
@override
int reduce() {
return state + incrementBy;
}
}
创建 ViewModel
BaseModel
是一个方便的类,可以快速为 Redux StoreConnector
创建 ViewModel。它直接访问 store 状态和 dispatch 函数。你可以在模型或小部件中 dispatch 动作。
class _VM extends BaseModel<int> {
final int? count;
_VM(Store<int> store, {this.count = 0}) : super(store);
void incrementCount() {
dispatch(IncrementCountAction(1));
}
@override
_VM fromStore() {
final count = state;
return _VM(store, count: count);
}
}
使用 StoreConnector
最后,在小部件中使用 StoreConnector
来初始化 ViewModel 并构建 UI。
class CounterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StoreConnector<int, _VM>(
converter: (store) => _VM(store).fromStore(), // 初始化 BaseModel
builder: (context, vm) => render(context, vm),
);
}
Widget render(BuildContext context, _VM vm) {
return Scaffold(
appBar: AppBar(
title: Text("Redux Compact"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
vm.count.toString(),
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: vm.incrementCount, // 通过 BaseModel dispatch
tooltip: "Increment",
child: Icon(Icons.add),
),
);
}
}
全局错误处理
你可以通过在创建中间件时实现 onError
函数来添加全局错误处理。该函数接受 dynamic error
和 dispatch
函数作为参数。
final compactMiddleware = ReduxCompact.createMiddleware<int>(
onError: (error, dispatch) => yourErrorFunction(error, dispatch),
);
Compact Action
为了使用 Redux Compact,你必须分发一个扩展 CompactAction
的动作。所有紧凑动作都必须实现 reduce
方法,这是动作的 reducer。reduce
方法可以直接访问实例变量、dispatch 函数和 store 状态。
同步动作
class IncrementCountAction extends CompactAction<int> {
final int incrementBy;
IncrementCountAction(this.incrementBy);
@override
int reduce() {
return state + incrementBy;
}
}
异步动作
要创建异步动作,只需实现 makeRequest()
方法作为一个 Future
。随着请求的执行,request
实例变量的值会改变,从而允许你根据情况进行状态更改。
class FetchDataAction extends CompactAction<AppState> {
@override
Future<void> makeRequest() async {
final url = "http://example.com/data";
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
return response.body;
} else {
throw Exception('Failed to load data');
}
}
@override
AppState reduce() {
if (request.loading) {
return state.copy(isLoading: request.loading);
}
if (request.hasError) {
return state.copy(errorMsg: request.error.toString());
}
return state.copy(data: request.data);
}
}
链式调用动作
Compact Action 提供了两个辅助函数:before
和 after
。这两个方法都可以直接访问 state
、dispatch
函数和类实例变量。因此,你可以在当前动作运行之前或之后调用或 dispatch 其他函数或动作。
class IncrementCountAction extends CompactAction<int> {
final int incrementBy;
IncrementCountAction(this.incrementBy);
@override
int reduce() {
return state + incrementBy;
}
@override
void before() {
dispatch(SetPreviousCountAction(state));
}
@override
void after() {
dispatch(FetchDataAction());
}
}
总结
Redux Compact 通过简化动作和 reducer 的定义,减少了大量样板代码,使得状态管理更加简洁高效。希望本文档能帮助你更好地理解和使用 Redux Compact。如果你有任何问题或建议,欢迎在评论区留言。
更多关于Flutter状态管理插件redux_compact的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter状态管理插件redux_compact的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,redux_compact
是一个用于状态管理的插件,它是对 Redux 模式的简化封装,使得状态管理更加简洁和高效。下面是一个使用 redux_compact
进行状态管理的代码示例,包括创建 Redux store、定义 actions 和 reducers,以及在 Flutter widget 中使用这些状态。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 redux_compact
的依赖:
dependencies:
flutter:
sdk: flutter
redux_compact: ^x.y.z # 替换为最新版本号
2. 定义状态 (State)
假设我们有一个简单的计数器应用,状态是一个整数:
import 'package:redux_compact/redux_compact.dart';
class CounterState implements StateType {
final int count;
CounterState(this.count);
// 实现 Equatable 的 props 方法,用于比较两个状态是否相等
@override
List<Object?> get props => [count];
}
3. 定义动作 (Actions)
接下来,定义增加和减少计数的动作:
import 'package:redux_compact/redux_compact.dart';
enum CounterActionTypes {
INCREMENT,
DECREMENT,
}
class CounterActions {
static Action increment() => Action(CounterActionTypes.INCREMENT);
static Action decrement() => Action(CounterActionTypes.DECREMENT);
}
4. 定义 Reducer
然后,定义处理这些动作的 reducer:
import 'package:redux_compact/redux_compact.dart';
import 'counter_state.dart';
import 'counter_actions.dart';
CounterState counterReducer(CounterState state, Action action) {
CounterState newState;
switch (action.type) {
case CounterActionTypes.INCREMENT:
newState = CounterState(state.count + 1);
break;
case CounterActionTypes.DECREMENT:
newState = CounterState(state.count - 1);
break;
default:
newState = state;
}
return newState;
}
5. 创建 Store
使用 ReduxCompact
创建 store,并传入初始状态和 reducer:
import 'package:redux_compact/redux_compact.dart';
import 'counter_state.dart';
import 'counter_reducer.dart';
final store = ReduxCompact<CounterState>(
initialState: CounterState(0),
reducer: counterReducer,
);
6. 在 Flutter Widget 中使用 Store
最后,在 Flutter widget 中使用 Provider
包装应用,并使用 connect
函数将状态和动作绑定到 widget:
import 'package:flutter/material.dart';
import 'package:redux_compact/redux_compact.dart';
import 'store.dart';
import 'counter_actions.dart';
void main() {
runApp(Provider<CounterState>(
store: store,
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterScreen(),
);
}
}
class CounterScreen extends StatelessWidget {
CounterScreen() {
// 使用 connect 函数将状态和动作绑定到 widget
connect<CounterState>(
mapStateToProps: (state) => ({
count: state.count,
}),
mapDispatchToProps: (dispatch) => ({
increment: () => dispatch(CounterActions.increment()),
decrement: () => dispatch(CounterActions.decrement()),
}),
component: this,
);
}
@override
Widget build(BuildContext context) {
final stateProps = getStateProps(context)!;
final dispatchProps = getDispatchProps(context)!;
return Scaffold(
appBar: AppBar(
title: Text('Counter'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${stateProps.count}',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: dispatchProps.increment,
tooltip: 'Increment',
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
在这个示例中,我们创建了一个简单的计数器应用,使用 redux_compact
管理应用的状态。connect
函数用于将 Redux store 的状态和操作映射到 Flutter widget 中,从而允许我们在 widget 中访问和修改状态。