参考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划分为不同数据模块的更多相关文章

  1. redux源码解析-redux的架构

    redux很小的一个框架,是从flux演变过来的,尽管只有775行,但是它的功能很重要.react要应用于生成环境必须要用flux或者redux,redux是flux的进化产物,优于flux. 而且r ...

  2. 关于 Unity WebGL 的探索(二)

    关于 Unity WebGL 的探索(二) 上一篇博客记录了关于 WebGL 移植的第一步:部分 C/C++ 插件的编译,目前项目中的部分插件使用该方法通过,接下来比较大的一部分工作量是网络模块 We ...

  3. react第十六单元(redux的认识,redux相关api的掌握)

    第十六单元(redux的认识,redux相关api的掌握) #课程目标 掌握组件化框架实现组件之间传参的几种方式,并了解两个没有任何关系组件之间通信的通点 了解为了解决上述通点诞生的flux架构 了解 ...

  4. react+redux教程(二)redux的单一状态树完全替代了react的状态机?

    上篇react+redux教程,我们讲解了官方计数器的代码实现,react+redux教程(一).我们发现我们没有用到react组件本身的state,而是通过props来导入数据和操作的. 我们知道r ...

  5. 动手实现 Redux(二):抽离 store 和监控数据变化

    上一节 的我们有了 appState 和 dispatch: let appState = { title: { text: 'React.js 小书', color: 'red', }, conte ...

  6. 二刷Redux笔记

    关于react的一些思考 所有的数据全部先要发送给容器,然后容器负责接受数据单后再分发数据给他下面的组件,通过props来传递,一个页面就可以相当于一个容器,容器之中就会有很多子组件,一般组件只负责接 ...

  7. [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 ...

  8. [Unity+Android]横版扫描二维码

    原地址:http://blog.csdn.net/dingxiaowei2013/article/details/25086835 终于解决了一个忧伤好久的问题,严重拖了项目进度,深感惭愧!一直被一系 ...

  9. Unity Shader 知识点总结(二)

    紧接着上一篇文章的shader入门知识的总结,本文主要总结shader中的纹理贴图.透明度混合.顶点动画.后期特效处理等操作.如果有什么地方有错,请指出更正,谢谢.本文的代码主要来自开源书:unity ...

  10. Redux学习笔记:Redux简易开发步骤

    该文章不介绍Redux基础,也不解释各种乱乱的概念,网上一搜一大堆.只讲使用Redux开发一个功能的步骤,希望可以类我的小白们,拜托它众多概念的毒害,大牛请绕道! 本文实例源代码参考:React-Re ...

随机推荐

  1. 从Excel 电子表格中读取数据并插入到数据库的简单方式

    using (FileStream fileStreamRead = new FileStream("new.xls" , FileMode.Open )) { //创建工作簿 I ...

  2. AcWing 4489. 最长子序列题解

    思路 此题较为简单,简述一下思路. 设原始数列为 \(a\). 定义 \(dp\) 数组,初始值都为 \(1\). 遍历数组,如果 \(a[i-1]*2 \leq a[i]\) ,那么 \(dp[i] ...

  3. 即构SDK7月迭代:新增支持按通道设置延迟模式,让卡顿大大减少

    即构SDK 7月迭代如期而至,本月SDK更新主要增加了按推流通道设置延迟模式,大大减少了直播卡顿:媒体本地录制新增AAC 格式,可生成更小的录制文件,更易于上传.此外还有多项功能的优化,让用户获得更好 ...

  4. Maven-Could not calculate build plan错误解决方法

    报错如图: 报错情况: 可以创建简单的maven项目例子,但是无法创建web的maven项目 解决方法: 1.安装maven插件后,c盘下会生成.m2文件夹 .m2\repository\org\ap ...

  5. HTB靶场之Sandworm

    准备: 攻击机:虚拟机kali. 靶机:Sandworm,htb网站:https://www.hackthebox.com/,靶机地址:https://app.hackthebox.com/machi ...

  6. MAUI中Windows的标题栏颜色怎么设置

    如下图所示,MAUI中Windows下的标题栏是灰色的,如何设置颜色,找了很久,在GitHub上的issue中找到了答案, 找到/Platforms/Windows/App.xaml <maui ...

  7. Qt 生成应用程序(二)软件多图标与文件操作

    目录 关联某种文件的默认打开方式 assoc ftype 解决方案 设置文件默认图标 应用软件添加多个图标 综合方法 嘿,各位Qt桌面应用开发的同学们(应该Qt大部分应用场景就是这个吧),上一篇文章中 ...

  8. JVM调优篇:探索Java性能优化的必备种子面试题

    JVM内存模型 首先面试官会询问你在进行JVM调优之前,是否了解JVM内存模型的基础知识.这是一个重要的入门问题.JVM内存模型主要包括程序计数器.堆.本地方法栈.Java栈和方法区(1.7之后更改为 ...

  9. JMeter 线程组之Stepping Thread Group插件

    JMeter 线程组之Stepping Thread Group插件 测试环境   apache-jmeter-2.13 插件:https://jmeter-plugins.org/downloads ...

  10. 预处理器 Less 的十个语法

    Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量.混合(mixin).函数等功能,让 CSS 更易维护.方便制作主题.扩充. 不过浏览器只能识别 CSS 语言,所以 Les ...