参考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. 基于GPT搭建私有知识库聊天机器人(四)问答实现

    前文链接: 基于GPT搭建私有知识库聊天机器人(一)实现原理 基于GPT搭建私有知识库聊天机器人(二)环境安装 基于GPT搭建私有知识库聊天机器人(三)向量数据训练 在前面的文章中,我们介绍了如何使用 ...

  2. BUUCTF-MISC-LSB(stegsolve的一种妙用)

    题目已知是LSB隐写 丢入stegsolve,点 > ,可以看见Red plane 0,Green plane 0,Blue plane 0上边好像有东西 点analyse->data e ...

  3. Git子模块使用说明

    介绍 前端不同应用存在公共的脚本或样式代码,为了避免重复开发,将公共的代码抽取出来,形成一个公共的 git 子模块,方便调用和维护. 软件架构 本仓库代码将作为 git 子模块,被引用到其他仓库中,不 ...

  4. 反汇编分析C语言

    环境 VC6.0环境 空函数反汇编 #include "stdafx.h" void function(){ } int main(int argc, char* argv[]) ...

  5. quarkus实战之七:使用配置

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<quarkus实战>系列 ...

  6. 01-jQuery的基本结构

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Java中的线程池使用及原理

    开篇-为什么要使用线程池? ​ Java 中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池能够带来 3 个好处. ​ 第一:降低 ...

  8. 人工智能如何应对 DevOps 监控和可观测性挑战

    自 ChatGPT 横空出世之后,AIGC 已成为不可逆转的时代浪潮.在之前的文章中,我们介绍了DevOps 领域中AI的用例,需要回顾可以点击下方链接.在本篇文章中,我将简单聊聊人工智能(AI)如何 ...

  9. Jmeter使用jp@gc-stepping thread group做性能测试

    扩展插件 下载地址:http://jmeter-plugins.org/downloads/all 将JMeterPlugins-Standard.jar复制到jmeter的lib目录下的ext目录下 ...

  10. 【Unity3D】反射和折射

    1 前言 ​ 立方体纹理(Cubemap)和天空盒子(Skybox)中介绍了生成立方体纹理和制作天空盒子的方法,本文将使用立方体纹理进行采样,实现反射.菲涅耳反射和折射效果.另外,本文还使用了 Gra ...