13 Redux
相信在前端领域、Redux 并不是一个陌生的概念,作为全局状态管理机,用于 Flutter 中再合适不过。如果你没听说过,Don't worry,简单来说就是:它可以跨控件管理、同步State 。所以 flutter_redux 等着你征服它。
大家都知道在 Flutter 中 ,是通过实现 State
与 setState
来渲染和改变 StatefulWidget
的,如果使用了flutter_redux
会有怎样的效果?
比如把用户信息存储在 redux
的 store
中, 好处在于: 比如某个页面修改了当前用户信息,所有绑定的该 State 的控件将由 Redux 自动同步修改,State 可以跨页面共享。
更多 Redux 的详细就不再展开,后续会有详细介绍,接下来我们讲讲 flutter_redux 的使用,在 redux 中主要引入了 action、reducer、store 概念。
- action 用于定义一个数据变化的请求。
- reducer 用于根据 action 产生新状态
- store 用于存储和管理 state,监听 action,将 action 自动分配给 reducer 并根据 reducer 的执行结果更新 state。
所以如下代码,我们先创建一个 State 用于存储需要保存的对象,其中关键代码在于 UserReducer
。
///全局Redux store 的对象,保存State数据
class GSYState {
///用户信息
User userInfo;
///构造方法
GSYState({this.userInfo});
}
///通过 Reducer 创建 用于store 的 Reducer
GSYState appReducer(GSYState state, action) {
return GSYState(
///通过 UserReducer 将 GSYState 内的 userInfo 和 action 关联在一起
userInfo: UserReducer(state.userInfo, action),
);
}
下面是上方使用的 UserReducer
的实现,这里主要通过 TypedReducer
将 reducer 的处理逻辑与定义的 Action 绑定,最后通过 combineReducers
返回 Reducer
对象应用于上方 Store 中。
/// redux 的 combineReducers, 通过 TypedReducer 将 UpdateUserAction 与 reducers 关联起来
final UserReducer = combineReducers<User>([
TypedReducer<User, UpdateUserAction>(_updateLoaded),
]);
/// 如果有 UpdateUserAction 发起一个请求时
/// 就会调用到 _updateLoaded
/// _updateLoaded 这里接受一个新的userInfo,并返回
User _updateLoaded(User user, action) {
user = action.userInfo;
return user;
}
///定一个 UpdateUserAction ,用于发起 userInfo 的的改变
///类名随你喜欢定义,只要通过上面TypedReducer绑定就好
class UpdateUserAction {
final User userInfo;
UpdateUserAction(this.userInfo);
}
下面正式在 Flutter 中引入 store,通过 StoreProvider
将创建 的 store 引用到 Flutter 中。
void main() {
runApp(new FlutterReduxApp());
}
class FlutterReduxApp extends StatelessWidget {
/// 创建Store,引用 GSYState 中的 appReducer 创建的 Reducer
/// initialState 初始化 State
final store = new Store<GSYState>(appReducer, initialState: new GSYState(userInfo: User.empty()));
FlutterReduxApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
/// 通过 StoreProvider 应用 store
return new StoreProvider(
store: store,
child: new MaterialApp(
home: DemoUseStorePage(),
),
);
}
}
在下方 DemoUseStorePage 中,通过 StoreConnector
将State 绑定到 Widget;通过 StoreProvider.of
可以获取 state 对象;通过 dispatch
一个 Action 可以更新State。
class DemoUseStorePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
///通过 StoreConnector 关联 GSYState 中的 User
return new StoreConnector<GSYState, User>(
///通过 converter 将 GSYState 中的 userInfo返回
converter: (store) => store.state.userInfo,
///在 userInfo 中返回实际渲染的控件
builder: (context, userInfo) {
return new Text(
userInfo.name,
style: Theme.of(context).textTheme.display1,
);
},
);
}
}
·····
///通过 StoreProvider.of(context) (带有 StoreProvider 下的 context)
/// 可以任意的位置访问到 state 中的数据
StoreProvider.of(context).state.userInfo;
·····
///通过 dispatch UpdateUserAction,可以更新State
StoreProvider.of(context).dispatch(new UpdateUserAction(newUserInfo));
看到这是不是有点想静静了?先不管静静是谁,但是Redux的实用性是应该比静静更吸引人,作为一个有追求的程序猿,多动手撸撸还有什么拿不下的山头是不?更详细的实现请看:GSYGithubAppFlutter 。
学员评价