主要介绍闲鱼出品的fish redux基础知识和使用,后续会有复杂应用场景分享。
flutter自带demo
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('$_counter'),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
flutter的计数demo,方便后面对比。
redux
简介Redux的流程
image<figcaption>redux 简介</figcaption>
简单说就是用户操作dispatcher(action),到reducer中处理相关数据和逻辑,存储数据到store中,更新state,触发UI刷新。
fish redux
部分重要概念 1. component 对局部的展示和功能的封装。对功能细分为修改数据的功能(Reducer)和非修改数据的功能(副作用Effect)。于是有了View、Effect、Reducer组件三要素。 2. action - Action 包含两个字段 - type - payload - 推荐的写法是 - 为一个组件|适配器创建一个 action.dart 文件,包含两个类 - 为 type 字段起一个枚举类 - 为 Action 的创建起一个 ActionCreator 类,这样利于约束 payload 的类型。 - Effect 接受处理的 Action,以 on{Verb} 命名 - Reducer 接受处理的 Action,以{verb} 命名 - 示例代码
enum MessageAction {
onShare,
shared,
}
class MessageActionCreator {
static Action onShare(Map<String, Object> payload) {
return Action(MessageAction.onShare, payload: payload);
}
static Action shared() {
return const Action(MessageAction.shared);
}
}
- reducer
- Reducer 是一个上下文无关的 pure function。它接收下面的参数
- T state
- Action action
- 它主要包含三方面的信息
- 接收一个“意图”, 做出数据修改。
- 如果要修改数据,需要创建一份新的拷贝,修改在拷贝上。
- 如果数据修改了,它会自动触发 State 的层层数据的拷贝,再以扁平化方式通知组件刷新。
- 示例代码
Reducer<String> buildMessageReducer() {
return asReducer(<Object, Reducer<String>>{
'shared': _shared,
});
}
String _shared(String msg, Action action) {
return '$msg [shared]';
}
class MessageComponent extends Component<String> {
MessageComponent(): super(
view: buildMessageView,
effect: buildEffect(),
reducer: buildMessageReducer(),
);
}
- effect 接收View的"意图",也包括对生命周期的回调。不修改数据,它对数据是只读的,如果要修改,应该发送一个Action到Reducer中去处理。
cunter fish redux 版
基础目录 > -action.dart > -effect.dart(本例中非必须) > -page.dart > -reducer.dart > -state.dart > -view.dart
action.dart
enum CounterAction { add, onAdd }
class CounterActionCreator {
//reducer使用
static Action add() {
return const Action(CounterAction.add);
}
//effect使用
static Action onAdd() {
return const Action(CounterAction.onAdd);
}
}
state.dart
class CounterState implements Cloneable<CounterState> {
int count = 0;
@override
CounterState clone() {
return CounterState()..count = count;
}
}
CounterState initState(Map<String, dynamic> args){
//什么也没做,只是初始化数据
return CounterState();
}
reducer.dart
Reducer<CounterState> buildReducer() {
return asReducer<CounterState>(<Object, Reducer<CounterState>>{
CounterAction.add: _add,
});
}
CounterState _add(CounterState state, Action action) {
final CounterState newState = state.clone();
newState.count = ++state.count;
return newState;
}
effect.dart
Effect<CounterState> buildEffect() {
return combineEffects(<Object, Effect<CounterState>>{
CounterAction.onAdd: _onAdd,
});
}
void _onAdd(Action action, Context<CounterState> ctx) {
print("_onAdd");
ctx.dispatch(CounterActionCreator.add());
}
view.dart
Widget buildView(
CounterState state, Dispatch dispatch, ViewService viewService) {
return Scaffold(
appBar: AppBar(
title: Text('CounterFishRedux'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
state.count.toString(),
)
],
),
),
floatingActionButton: FloatingActionButton(
//发送的action到了Effect中处理
onPressed: () => dispatch(CounterActionCreator.onAdd()),
//也可以发action到reducer中处理
//onPressed: () => dispatch(CounterActionCreator.add()),
tooltip: 'add',
child: Icon(Icons.add),
),
);
}
page.dart
class CounterFishReduxPage extends Page<CounterState, Map<String, dynamic>> {
CounterFishReduxPage()
: super(
initState: initState,
effect: buildEffect(),
reducer: buildReducer(),
view: buildView,
);
}
在view.dart中,用户触发FloatingActionButton的onPress事件,dispatch了名为onAdd的Action,在effect.dart中接收到action,会继续dispatch,到reducer.dart中(这一步非必须,可以直接dispatch到reducer.dart中),在reducer.dart中,在state中取出state中的数据,处理(加一)后,返回state,数据更新到store中,触发UI更新,最终到view.dart中state中的数据会更新,取出新的数据显示。
fish redux适用于中大型项目,这种简单的功能直接用官方的setState
即可。
这样就可以单独作为一个page或者component使用,没有逻辑和UI的耦合。
转自:https://zhuanlan.zhihu.com/p/62600189
资源推荐
github 上的库包含基本小部件的代码以及可以在该小部件中应用的大多数属性。
https://github.com/PoojaB26/FlutterBasicWidgets
最佳教程集合
https://github.com/PoojaB26/AwesomeFlutterPlaylist
flutter 介绍
https://github.com/Solido/awesome-flutter
https://github.com/CarGuo/GSYGithubAppWeex
网友评论