flutter fish redux使用簡介

主要介紹閑魚出品的fish redux基礎知識和使用,后續(xù)會有復雜應用場景分享。

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,觸發(fā)UI刷新。

fish redux

部分重要概念 1. component 對局部的展示和功能的封裝。對功能細分為修改數據的功能(Reducer)和非修改數據的功能(副作用Effect)。于是有了View、Effect、Reducer組件三要素。 2. action - Action 包含兩個字段 - type - payload - 推薦的寫法是 - 為一個組件|適配器創(chuàng)建一個 action.dart 文件,包含兩個類 - 為 type 字段起一個枚舉類 - 為 Action 的創(chuàng)建起一個 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);
    }
}
  1. reducer
  2. Reducer 是一個上下文無關的 pure function。它接收下面的參數
  • T state
  • Action action
  1. 它主要包含三方面的信息
  • 接收一個“意圖”, 做出數據修改。
  • 如果要修改數據,需要創(chuàng)建一份新的拷貝,修改在拷貝上。
  • 如果數據修改了,它會自動觸發(fā) State 的層層數據的拷貝,再以扁平化方式通知組件刷新。
  1. 示例代碼
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(),
        );
}
  1. effect 接收View的"意圖",也包括對生命周期的回調。不修改數據,它對數據是只讀的,如果要修改,應該發(fā)送一個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(
      //發(fā)送的action到了Effect中處理
      onPressed: () => dispatch(CounterActionCreator.onAdd()),
      //也可以發(fā)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中,用戶觸發(fā)FloatingActionButton的onPress事件,dispatch了名為onAdd的Action,在effect.dart中接收到action,會繼續(xù)dispatch,到reducer.dart中(這一步非必須,可以直接dispatch到reducer.dart中),在reducer.dart中,在state中取出state中的數據,處理(加一)后,返回state,數據更新到store中,觸發(fā)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

https://github.com/CarGuo/GSYGithubAppWeex

完整開源項目推薦:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容