10、Flutter Fish redux使用Store进行全局状态管理

store的作用主要是对全局状态进行管理,但并不是每个组件或者页面都要使用它,只有真正使用到这个全局状态时,组件或者页面的state去implements就可以了。

创建Store

在lib下创建一个store的包,然后,我们拿app主题色为例:
这里,我们不是去写一个组件或者是一个页面,而是单纯的对状态进行管理,所以不需要专门使用插件进行生成。当然也可以插件生成,然后手动修改,看个人需要。
第一步,需要创建一个全局state,这个state中只有一个themeColor的属性(也可以多个,比如字体颜色、大小等)。--store/store.dart

import 'dart:ui';
import 'package:fish_redux/fish_redux.dart';

abstract class GlobalBaseState{
  Color get themeColor;
  set themeColor(Color color);
}

class GlobalState implements GlobalBaseState, Cloneable<GlobalState>{
  @override
  Color themeColor;

  @override
  GlobalState clone() {
    return GlobalState();
  }
}

这里我们创建了一个全局的状态--GlobalState,它是在抽象GlobalBaseState基础上创建的。
第二步,我们来创建管理这个全局状态的意图Action及针对这个意图的处理reducer。
--store/action.dart & store/reducer.dart
Action:

import 'package:fish_redux/fish_redux.dart';

enum GlobalAction { changeThemeColor }

class GlobalActionCreator{
  static Action onChangeThemeColor(){
    return const Action(GlobalAction.changeThemeColor);
  }
}

定义这个意图名:changeThemeColor
然后处理reducer:

import 'package:fish_redux/fish_redux.dart';
import 'dart:ui';
import 'package:flutter/material.dart' hide Action;
import 'action.dart';
import 'state.dart';

Reducer<GlobalState> buildReducer(){
  return asReducer(
    <Object, Reducer<GlobalState>>{
      GlobalAction.changeThemeColor: _onChangeThemeColor,
    },
  );
}

GlobalState _onChangeThemeColor(GlobalState state, Action action){
  final Color color = state.themeColor == Colors.green ? Colors.blue : Colors.green;
  return state.clone()..themeColor = color;
}

意图--Action changeThemeColor的具体处理实现:_onChangeThemeColor,切换主题色。
第三步我们就可以创建store。--store/store.dart

import 'package:fish_redux/fish_redux.dart';
import 'state.dart';
import 'reducer.dart';

class GlobalStore{
  static Store<GlobalState> _globalStore;
  static Store<GlobalState> get store =>
      _globalStore ??= createStore<GlobalState>(GlobalState(), buildReducer());
}

GlobalStore创建需要GlobalState及reducer。

使用GlobalStore

首先,我们需要在入口处加一个页面的判断,判断页面的state有没有implements 全局的state,即:implements GlobalBaseState

import 'package:fish_demo/list/page.dart';
import 'package:fish_demo/splash/page.dart';
import 'package:fish_demo/store/state.dart';
import 'package:fish_demo/store/store.dart';
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart';

import 'entrance/page.dart';
import 'grid/page.dart';

Widget createApp(){
  final AbstractRoutes routes = PageRoutes(
      pages:<String,Page<Object,dynamic>>{
        'splash_page':SplashPage(),
        'entrance_page':EntrancePage(),
        'grid_page':GridPage(),
        'list_page':ListPage(),
      } ,
//重点-----
    visitor: (String path,Page<Object, dynamic> page){ 
        if(page.isTypeof<GlobalBaseState>()){
          page.connectExtraStore<GlobalState>(GlobalStore.store, (Object pageState,GlobalState appState){
            final GlobalBaseState p = pageState;
            if(p.themeColor !=appState.themeColor){
              if(pageState is Cloneable){
                final Object copy = pageState.clone();
                final GlobalBaseState newState = copy;
                newState.themeColor = appState.themeColor;
                return newState;
              }
            }
            return pageState;
          });
        }
    },
  );

然后,page中的使用就跟fish redux一样了,我们在触发处dispatch这个page下声明的相关意图给到effect,在effect中直接使用GlobalStore.store.dispatch给到全局状态的处理reducer进行处理。
当前page下action中声明,view组件中触发:

import 'package:fish_redux/fish_redux.dart';

//TODO replace with your own action
enum ItemAction { changeThemeColor }
  static Action changeThemeColor(){
    return const Action(ItemAction.changeThemeColor);
  }
}
......
view中触发:
onTap: (){
        dispatch(ItemActionCreator.changeThemeColor());
      },

当前page下effect中直接处理:

import 'package:fish_demo/store/action.dart';
import 'package:fish_demo/store/store.dart';
import 'package:fish_redux/fish_redux.dart';
import 'action.dart';
import 'state.dart';

Effect<ItemState> buildEffect() {
  return combineEffects(<Object, Effect<ItemState>>{
    ItemAction.changeThemeColor: _onChangeThemeColor,
  });
}
void _onChangeThemeColor(Action action,Context<ItemState> ctx){
//发送改变全局状态意图:
  GlobalStore.store.dispatch(GlobalActionCreator.onChangeThemeColor());
}

这时,全局状态的reducer接收到GlobalAction.changeThemeColor就开始进行全局状态处理。即:调用 _onChangeThemeColor。store/reducer.dart

GlobalState _onChangeThemeColor(GlobalState state, Action action){
  final Color color = state.themeColor == Colors.green ? Colors.blue : Colors.green;
  return state.clone()..themeColor = color;
}

具体实现可参考对应demo:https://gitee.com/lagman/fish_redux_demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。