参考QF.UIWidgets
参考Unity官方示例 - ConnectAppCN
前面说过,当时没想明白一个问题,在reducer中每次返回一个new State()
, 会造成极大浪费,没想到用什么办法来解决。
然后发现这些示例里面并没有每次创建一个新的State,只是直接修改了相应的值……那这样就简单多了。把Redux结构划分为不同数据模块,更方面管理。
在这里从头做一个简单的demo,包含两个页面:“homepage”,显示一条信息, “newpage”,显示一个计数
入口
// Main.cs
using System.Collections.Generic;
using Unity.UIWidgets;
using Unity.UIWidgets.engine;
using Unity.UIWidgets.material;
using Unity.UIWidgets.Redux;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Redux.State;
using Redux.Reducer;
using Redux.View;
namespace Redux
{
public class Main : UIWidgetsPanel
{
protected override void OnEnable()
{
base.OnEnable();
}
protected override Widget createWidget()
{
var widget = new MaterialApp(
initialRoute: "/",
routes: new Dictionary<string, WidgetBuilder>()
{
{ "/", context => new HomePage() },
{ "new", context => new NewPage() },
}
);
var store = new Store<AppState>(
reducer: AppReducer.Reduce,
initialState: new AppState()
);
return new StoreProvider<AppState>(
child: widget,
store: store
);
}
}
}
View部分
// View/HomePage.cs
// 因为这里不是重点,NewPage略
using System;
using System.Collections.Generic;
using Unity.UIWidgets.materal;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.Redux;
using Unity.UIWidgets.widgets;
using UnityEngine;
namespace Redux.View
{
public class HomePage : StatelessWidget
{
var widget = new Scaffold(
appBar: new appBar(
title: new Text("Home")
),
body: new Center(
children: new List<Widget>
{
new StoreConnector<AppState, string>(
converter: (state) => state.globalState.message,
builder: (context1, text, dispatcher) => new Text(text)
),
new StoreConnector<AppState, object>(
converter: (state) => null,
builder: (context2, _, dispatcher) => new RaisedButton(
child: new Text("当前时间"),
onPressed: () => {
dispatcher.dispatch(new Action.Global.SetMessageAction
{
message = DateTime.Now.ToString()
});
}
)
),
new RaisedButton(
child: new Text("打开新页面"),
onPressed: () => {
Navigator.pushNamed(context, "new");
}
)
}
)
);
return widget;
}
}
State部分
// State/AppState.cs
namespace Redux.State
{
public class AppState
{
public BagState bagState;
public GlobalState globalState;
public static AppState GetState()
{
AppState = new AppState
{
bagState = new BagState
{
itemCount = 0;
},
globalState = new GlobalState
{
message = "hello",
},
}
}
}
}
// State/BagState.cs
namespace Redux.State
{
public class BagState
{
public int itemCount;
}
}
// State/GlobalState.cs
namespace Redux.State
{
public class GlobalState
{
public string message;
}
}
Action部分
// Action/BagAction.cs
namespace Redux.Action
{
public interface IBagAction {}
}
namespace Redux.Action.Bag
{
public class AddCountAction : IBagAction
{
public int count;
}
public class RemoveCountAction : IBagAction
{
public int count;
}
}
// Action/GlobalAction.cs
namespace Redux.Action
{
public interface IGlobalAction {}
}
namespace Redux.Action.Global
{
public class SetMessageAction : IGlobalAction
{
public string message;
}
}
Reducer部分
// Reducer/AppReducer.cs
using Redux.Action;
using Redux.State;
namespace Redux.Reducer
{
public static class AppReducer
{
public static AppState Reduce(AppState state, object action)
{
switch (action)
{
case IBagAction bagAction:
return BagReducer.Reduce(state, bagAction);
case IGlobalAction globalAction:
return GlobalReducer.Reduce(state, globalAction);
default:
return state;
}
}
}
}
// Reducer/BagReducer.cs
using Redux.Action;
using Redux.Action.Bag;
using Redux.State;
namespace Redux.Reducer
{
public static class BagReducer
{
public static AppState Reduce(AppState state, IBagAction action)
{
switch (action)
{
case AddCountAction addCountAction:
return OnAddCountAction(state, addCountAction);
case RemoveCountAction removeCountAction:
return OnRemoveCountAction(state, removeCountAction);
default:
return state;
}
}
private static AppState OnAddCountAction(AppState state, AddCountAction action)
{
state.bagState.itemCount += action.count;
return state;
}
private static AppState OnRemoveCountAction(AppState state, RemoveCountAction action)
{
state.bagState.itemCount -= action.count;
return state;
}
}
}
// Reducer/GlobalReducer.cs
using Redux.Action;
using Redux.Action.Global;
using Redux.State;
namespace Redux.Reducer
{
public static class GlobalReducer
{
public static AppState Reduce(AppState state, IGlobalAction action)
{
switch (action)
{
case SetMessageAction setMessageAction:
return OnSetMessageAction(state, setMessageAction);
default:
return state;
}
}
private static AppState OnSetMessageAction(AppState state, SetMessageAction action)
{
state.globalState.message = action.message;
return state;
}
}
}
按这样的模式,redux部分(仅此部分)可以考虑写相应的代码生成工具了