Unity - UIWidgets 7. Redux接入(二) 把Redux划分为不同数据模块
参考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部分(仅此部分)可以考虑写相应的代码生成工具了
Unity - UIWidgets 7. Redux接入(二) 把Redux划分为不同数据模块的更多相关文章
- redux源码解析-redux的架构
redux很小的一个框架,是从flux演变过来的,尽管只有775行,但是它的功能很重要.react要应用于生成环境必须要用flux或者redux,redux是flux的进化产物,优于flux. 而且r ...
- 关于 Unity WebGL 的探索(二)
关于 Unity WebGL 的探索(二) 上一篇博客记录了关于 WebGL 移植的第一步:部分 C/C++ 插件的编译,目前项目中的部分插件使用该方法通过,接下来比较大的一部分工作量是网络模块 We ...
- react第十六单元(redux的认识,redux相关api的掌握)
第十六单元(redux的认识,redux相关api的掌握) #课程目标 掌握组件化框架实现组件之间传参的几种方式,并了解两个没有任何关系组件之间通信的通点 了解为了解决上述通点诞生的flux架构 了解 ...
- react+redux教程(二)redux的单一状态树完全替代了react的状态机?
上篇react+redux教程,我们讲解了官方计数器的代码实现,react+redux教程(一).我们发现我们没有用到react组件本身的state,而是通过props来导入数据和操作的. 我们知道r ...
- 动手实现 Redux(二):抽离 store 和监控数据变化
上一节 的我们有了 appState 和 dispatch: let appState = { title: { text: 'React.js 小书', color: 'red', }, conte ...
- 二刷Redux笔记
关于react的一些思考 所有的数据全部先要发送给容器,然后容器负责接受数据单后再分发数据给他下面的组件,通过props来传递,一个页面就可以相当于一个容器,容器之中就会有很多子组件,一般组件只负责接 ...
- [Redux + Webpack] Hot reloading Redux Reducers with Webpack
Webpack will hot reload the component, but the reducer we need hard refresh. To sovle the problem, g ...
- [Unity+Android]横版扫描二维码
原地址:http://blog.csdn.net/dingxiaowei2013/article/details/25086835 终于解决了一个忧伤好久的问题,严重拖了项目进度,深感惭愧!一直被一系 ...
- Unity Shader 知识点总结(二)
紧接着上一篇文章的shader入门知识的总结,本文主要总结shader中的纹理贴图.透明度混合.顶点动画.后期特效处理等操作.如果有什么地方有错,请指出更正,谢谢.本文的代码主要来自开源书:unity ...
- Redux学习笔记:Redux简易开发步骤
该文章不介绍Redux基础,也不解释各种乱乱的概念,网上一搜一大堆.只讲使用Redux开发一个功能的步骤,希望可以类我的小白们,拜托它众多概念的毒害,大牛请绕道! 本文实例源代码参考:React-Re ...
随机推荐
- 【调制解调】AM 调幅
说明 学习数字信号处理算法时整理的学习笔记.同系列文章目录可见 <DSP 学习之路>目录.本篇介绍 AM 调幅信号的调制与解调,内附全套 MATLAB 代码. 目录 说明 1. AM 调制 ...
- #Powerbi 10分钟,理解 Rankx 排名函数
一:本文思维导图及示例数据图 1.1思维导图 1.2 示例数据图 二:度量值示例 2.1 函数简介 RANKX 首先为的每一行计值表达式,将结果临时存储为一个值列表.然后在当前筛选上下文中计值,将得 ...
- CentOS上安装Redis的两种方式
今天小编给大家介绍下,如何在CentOS上安装Redis.通常有两种方式:第一种是通过下载源码并编译来安装,第二种是通过仓库直接安装.相较而言,第二种方式更直截了当,但小编更倾向第一种. 一.通过源码 ...
- OceanBase 分布式存储管理
分布式存储管理 分区表管理 定义 把普通的表的数据按照一定的规则划分到不同的区块内,同一区块的数据物理上存储在一起. 每个分区还能按照一定的规则再拆分成多个分区,这种分区表叫做二级分区表. 分区分类 ...
- Llama2 论文中译版——开放式基础和微调聊天模型
Llama 2:开放式基础和微调聊天模型 写在前头 因为最近一直在使用 LLM 工具,所以在学习 Llama 2:开放式基础和微调聊天模型 这篇论文的期间,顺手将内容翻译了过来. 整片译文是由 Cha ...
- python移动文件
#移动文件(目录) shutil.move("oldpos","newpos") shutil.move("D:/知乎日报/latest/一张优惠券, ...
- 基于C#的窗体阴影效果方案 - 开源研究系列文章
最近在研究C#的Winform窗体的效果,上次介绍了窗体动画效果的博文( 基于C#的无边框窗体动画效果的完美解决方案 - 开源研究系列文章 ),这次将窗体阴影效果的方案进行一个介绍. 找了一下度娘,具 ...
- 一种flink 作业提交失败的情况描述与原因排查
遇到异常 2019-12-24 16:49:59,019 INFO org.apache.flink.yarn.YarnClusterClient - Starting client actor sy ...
- Redis从入门到放弃(8):哨兵模式
在前面的文章中介绍了Redis的主从复制,但主从复制存在一定的缺陷.如果Master节点宕机,因为不具备自动恢复功能,需要人工干预,那么在这个干预过程中Redis将不可用. 为了解决这一问题,Redi ...
- 【RocketMQ】MQ消息发送总结
RocketMQ是通过DefaultMQProducer进行消息发送的,它实现了MQProducer接口,MQProducer接口中定义了消息发送的方法,方法主要分为三大类: send同步进行消息发送 ...