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{
  @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 buildReducer(){
  return asReducer(
    >{
      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 _globalStore;
  static Store get store =>
      _globalStore ??= createStore(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:>{
        'splash_page':SplashPage(),
        'entrance_page':EntrancePage(),
        'grid_page':GridPage(),
        'list_page':ListPage(),
      } ,
//重点-----
    visitor: (String path,Page page){ 
        if(page.isTypeof()){
          page.connectExtraStore(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 buildEffect() {
  return combineEffects(>{
    ItemAction.changeThemeColor: _onChangeThemeColor,
  });
}
void _onChangeThemeColor(Action action,Context 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

你可能感兴趣的:(10、Flutter Fish redux使用Store进行全局状态管理)